﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows;
using System.Windows.Media;
using CPlatePrintSys.Annotation.Converters;
using System.Windows.Media.Media3D;
using HelixToolkit.Wpf;
using netDxf.Entities;
using netDxf;
using Prism.Events;
using CPlatePrintSys.Annotation.Events;
using CPlatePrintSys.Annotation.Models;
using netDxf.Collections;
using System.Xml.Linq;
using System.Windows.Input;
using Point = System.Windows.Point;
using System.Windows.Controls.Primitives;
using System.Windows.Media.Imaging;
using static System.Net.Mime.MediaTypeNames;
using Text = netDxf.Entities.Text;
using CPlatePrintSys.Domain.Services;
using CPlatePrintSys.Domain.Models;

namespace CPlatePrintSys.Annotation.Controls
{
    /// <summary>  
    /// 基于HelixToolkit的3D展示控件，用于展示标注信息的效果及根据修改后的标注信息进行UI刷新。  
    /// </summary>  
    public class AnnotationDisplayerControl : HelixViewport3D
    {
        /// <summary>
        /// 镜像变换管理器 - 集中处理所有镜像相关的变换计算
        /// </summary>
        private class MirrorTransformManager
        {
            private readonly string _controlId;
            private readonly AnnotationDisplayerControl _parentControl;

            public MirrorTransformManager(string controlId, AnnotationDisplayerControl parentControl)
            {
                _controlId = controlId;
                _parentControl = parentControl;
            }

            /// <summary>
            /// 检查当前控件是否为镜像控件
            /// </summary>
            public bool IsMirrorControl => _controlId == "mirror";

            /// <summary>
            /// 应用镜像变换到位置
            /// </summary>
            public Point3D TransformPosition(Point3D originalPosition, double rotation, double height)
            {
                if (!IsMirrorControl) return originalPosition;
                return _parentControl.GetImprovedMirroredPosition(originalPosition, rotation, height);
            }

            /// <summary>
            /// 应用镜像变换到旋转角度
            /// </summary>
            public double TransformRotation(double originalRotation)
            {
                if (!IsMirrorControl) return originalRotation;
                return _parentControl.GetImprovedMirroredRotation(originalRotation);
            }

            /// <summary>
            /// 获取镜像文字的方向向量
            /// </summary>
            public (Vector3D overVector, Vector3D upVector) GetTextDirectionVectors(double rotation)
            {
                if (!IsMirrorControl)
                {
                    return (new Vector3D(1, 0, 0), new Vector3D(0, 1, 0));
                }

                Vector3D over, up;
                _parentControl.CalculateTextDirectionVectors(rotation, out over, out up, true);
                return (over, up);
            }

            /// <summary>
            /// 计算镜像变换的移动角度
            /// </summary>
            public double CalculateMirrorMoveRotation(double originalRotation)
            {
                if (!IsMirrorControl) return 0;
                var destRotation = TransformRotation(originalRotation);
                return AnnotationDisplayerControl.GetCCWAngle(originalRotation, destRotation);
            }

            /// <summary>
            /// 创建镜像文字视觉对象（对外部透明，自动处理镜像变换）
            /// </summary>
            public ModelVisual3D CreateMirrorTextVisual(string text, Brush color, bool doubleSided,
                double height, Point3D position, double rotation, string fontFamily, bool underline, double originalRotation = 0)
            {
                if (!IsMirrorControl)
                {
                    return AnnotationDisplayerControl.GetTextVisual(text, color, false, height, position,
                        new Vector3D(1, 0, 0), new Vector3D(0, 1, 0), rotation, fontFamily, underline);
                }

                // 镜像控件：自动进行坐标和角度变换，对外部透明
                var mirroredPosition = TransformPosition(position, rotation, height);
                var mirroredRotation = TransformRotation(rotation);

                // 计算镜像文字方向向量
                var (overVector, upVector) = GetTextDirectionVectors(mirroredRotation);

                // 计算移动角度（使用原始角度和变换后角度的差值）
                var moveRotation = originalRotation != 0 ?
                    AnnotationDisplayerControl.GetCCWAngle(originalRotation, mirroredRotation) :
                    AnnotationDisplayerControl.GetCCWAngle(rotation, mirroredRotation);

                return AnnotationDisplayerControl.GetMirrorTextVisual(text, color, true, height, mirroredPosition,
                    overVector, upVector, moveRotation, fontFamily, underline);
            }

            /// <summary>
            /// 创建镜像MText视觉对象（对外部透明，自动处理镜像变换）
            /// </summary>
            public ModelVisual3D CreateMirrorMTextVisual(string text, Brush color, bool doubleSided,
                double height, Point3D position, double rotation, Vector3D offset, string fontFamily, bool underline)
            {
                if (!IsMirrorControl)
                {
                    return AnnotationDisplayerControl.GetMTextVisual(text, color, doubleSided, height, position,
                        new Vector3D(1, 0, 0), new Vector3D(0, 1, 0), rotation, offset, fontFamily, underline);
                }

                // 镜像控件：自动进行坐标和角度变换，对外部透明
                var mirroredPosition = TransformPosition(position, rotation, height);
                var mirroredRotation = TransformRotation(rotation);

                // 计算镜像文字方向向量
                var (overVector, upVector) = GetTextDirectionVectors(mirroredRotation);

                // 计算移动角度
                var moveRotation = AnnotationDisplayerControl.GetCCWAngle(rotation, mirroredRotation);

                return AnnotationDisplayerControl.GetMTextVisual(text, color, true, height, mirroredPosition,
                    overVector, upVector, moveRotation, offset, fontFamily, underline);
            }
        }


        public static readonly DependencyProperty ControlIdProperty = DependencyProperty.Register(
            nameof(ControlId), typeof(string), typeof(AnnotationDisplayerControl), new PropertyMetadata(null, OnControlIdChanged));

        /// <summary>
        /// 控件唯一标识，用于事件隔离
        /// </summary>
        public string ControlId
        {
            get => (string)GetValue(ControlIdProperty);
            set => SetValue(ControlIdProperty, value);
        }

        /// <summary>
        /// ControlId属性变化回调
        /// </summary>
        private static void OnControlIdChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (d is AnnotationDisplayerControl control)
            {
                System.Diagnostics.Debug.WriteLine($"=== ControlId属性变化 ===");
                System.Diagnostics.Debug.WriteLine($"控件类型: {control.GetType().Name}");
                System.Diagnostics.Debug.WriteLine($"旧值: '{e.OldValue ?? "null"}'");
                System.Diagnostics.Debug.WriteLine($"新值: '{e.NewValue ?? "null"}'");

                // 当ControlId被设置后，初始化镜像变换管理器
                if (!string.IsNullOrEmpty(e.NewValue as string))
                {
                    control.InitializeMirrorTransformManager();
                }

                System.Diagnostics.Debug.WriteLine($"=== ControlId属性变化完成 ===");
            }
        }

        // 修改字段名称以避免二义性  
        private readonly IEventAggregator _eventAggregatorInstance;

        // 镜像变换管理器
        private MirrorTransformManager _mirrorTransformManager;

        /// <summary>
        /// 初始化镜像变换管理器
        /// </summary>
        private void InitializeMirrorTransformManager()
        {
            if (_mirrorTransformManager == null && !string.IsNullOrEmpty(this.ControlId))
            {
                _mirrorTransformManager = new MirrorTransformManager(this.ControlId, this);
                System.Diagnostics.Debug.WriteLine($"镜像变换管理器已初始化，ControlId: {this.ControlId}");
            }
        }

        /// <summary>
        /// 安全获取镜像变换管理器，如果未初始化则先初始化
        /// </summary>
        private MirrorTransformManager GetMirrorTransformManager()
        {
            if (_mirrorTransformManager == null)
            {
                InitializeMirrorTransformManager();
            }
            return _mirrorTransformManager;
        }

        private Dictionary<string, ModelVisual3D> _annotationModels = new Dictionary<string, ModelVisual3D>();
        private Dictionary<string, ModelVisual3D> _entityVisualMap = new Dictionary<string, ModelVisual3D>(); // 实体ID到ModelVisual3D的映射

        // 添加边界值作为成员变量  
        private double _minX = double.MaxValue;
        private double _minY = double.MaxValue;
        private double _maxX = double.MinValue;
        private double _maxY = double.MinValue;

        private Point3D? _startPoint3D = null;
        private LinesVisual3D _rubberBandLine3D = null;

        /// <summary>
        /// 当前编辑模式，默认为无
        /// </summary>
        private EditingMode _currentEditingMode = EditingMode.None;

        // 文字选中相关字段
        private ModelVisual3D _selectedTextVisual = null;
        private Material _originalMaterial = null;
        private string _selectedTextId = null;
        private Dictionary<string, TextInfo> _textInfoMap = new Dictionary<string, TextInfo>();
        private TextInfo _selectedTextInfo = null; // 当前选中的文字信息
        private double _lastRotateAngle = 0; // 上次旋转角度

        // 编辑辅助元素
        private TextEditAdorner _textEditAdorner;
        private bool _isDraggingText = false;
        private bool _isRotating = false;
        private Point3D _dragStartTextPos;
        private Point _dragStartMousePos;
        private double _dragStartRotation;

        // 新增：管理当前编辑框，确保同时只有一个编辑框存在
        private TextEditBoxAdorner _currentEditAdorner = null;

        // 拖拽交互相关
        private bool _isResizing = false;
        private int _resizeHandleIndex = -1;
        private double _dragStartHeight;
        private Point _dragStartOppositeHandleCenter; // 2D opposite handle center

        // 旋转交互相关
        private Point _rotateCenter2D; // 2D rotation center
        private double _rotateStartAngle; // 鼠标起始极角
        private double _rotateOriginAngle; // 文字原始角度

        private Brush _originalTextBrush = null;

        private Point? _mouseDownPos;
        private bool _isDragGesture = false; // True when mouse has moved beyond drag threshold

        // 鼠标交互灵敏度配置
        private double _rotateHandleExpansion = 12; // 旋转手柄检测区域扩展像素
        private double _resizeHandleExpansion = 6;  // 调整大小手柄检测区域扩展像素


        /// <summary>
        /// 图层颜色配置
        /// </summary>
        private Dictionary<string, Color> _layerNameToColorMap = new Dictionary<string, Color>();

        /// <summary>
        /// 设置鼠标交互灵敏度
        /// </summary>
        /// <param name="rotateExpansion">旋转手柄检测区域扩展像素（默认12）</param>
        /// <param name="resizeExpansion">调整大小手柄检测区域扩展像素（默认6）</param>
        public void SetMouseInteractionSensitivity(double rotateExpansion = 12, double resizeExpansion = 6)
        {
            _rotateHandleExpansion = Math.Max(0, rotateExpansion);
            _resizeHandleExpansion = Math.Max(0, resizeExpansion);
        }


        /// <summary>
        /// 构建图层名称到颜色的映射
        /// </summary>
        private void BuildLayerNameToColorMap()
        {
            try
            {
                _layerNameToColorMap.Clear();
                var configService = (IGlobalConfigService)Prism.Ioc.ContainerLocator.Container?.Resolve(typeof(IGlobalConfigService));
                if (configService != null)
                {
                    // 使用Task.Run在后台线程执行数据库操作，避免UI线程阻塞
                    var colorConfigTask = Task.Run(async () =>
                    {
                        try
                        {
                            // 添加超时机制，避免永久等待
                            using (var cts = new System.Threading.CancellationTokenSource(TimeSpan.FromSeconds(10)))
                            {
                                return await configService.GetLayerColorConfigAsync().ConfigureAwait(false);
                            }
                        }
                        catch (OperationCanceledException)
                        {
                            System.Diagnostics.Debug.WriteLine("获取图层颜色配置超时，使用默认配置");
                            return new LayerColorConfig();
                        }
                        catch (Exception ex)
                        {
                            System.Diagnostics.Debug.WriteLine($"获取图层颜色配置失败: {ex.Message}");
                            return new LayerColorConfig();
                        }
                    });

                    // 等待任务完成，但设置超时
                    if (colorConfigTask.Wait(TimeSpan.FromSeconds(15)))
                    {
                        var colorConfig = colorConfigTask.Result;
                        _layerNameToColorMap = new Dictionary<string, Color>
                        {
                            { "划线层", HexToColor(colorConfig.LineLayerColor) },
                            { "印字层", HexToColor(colorConfig.TextLayerColor) },
                            { "不印字划线层", HexToColor(colorConfig.InfoLayerColor) },
                            // 支持英文图层名称
                            { "LINE", HexToColor(colorConfig.LineLayerColor) },
                            { "TEXT", HexToColor(colorConfig.TextLayerColor) },
                            { "DASH", HexToColor(colorConfig.InfoLayerColor) }
                        };
                    }
                    else
                    {
                        System.Diagnostics.Debug.WriteLine("构建图层颜色映射超时，使用默认配置");
                        BuildDefaultLayerColorMap();
                    }
                }
                else
                {
                    System.Diagnostics.Debug.WriteLine("无法获取全局配置服务，使用默认配置");
                    BuildDefaultLayerColorMap();
                }
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine($"构建图层颜色映射时发生异常: {ex.Message}");
                BuildDefaultLayerColorMap();
            }
        }

        /// <summary>
        /// 构建默认的图层颜色映射
        /// </summary>
        private void BuildDefaultLayerColorMap()
        {
            _layerNameToColorMap = new Dictionary<string, Color>
            {
                { "划线层", Colors.Green },
                { "印字层", Colors.Orange },
                { "不印字划线层", Colors.Blue },
                // 支持英文图层名称
                { "LINE", Colors.Green },
                { "TEXT", Colors.Orange },
                { "DASH", Colors.Blue }
            };
        }

        /// <summary>
        /// 将十六进制颜色字符串转换为Color对象
        /// </summary>
        private Color HexToColor(string hexColor)
        {
            try
            {
                if (string.IsNullOrEmpty(hexColor) || !hexColor.StartsWith("#"))
                    return Colors.Black;

                string hex = hexColor.TrimStart('#');
                if (hex.Length == 6)
                {
                    byte r = Convert.ToByte(hex.Substring(0, 2), 16);
                    byte g = Convert.ToByte(hex.Substring(2, 2), 16);
                    byte b = Convert.ToByte(hex.Substring(4, 2), 16);
                    return Color.FromRgb(r, g, b);
                }
            }
            catch
            {
                // 转换失败时返回默认颜色
                System.Diagnostics.Debug.WriteLine($"颜色转换失败: {hexColor}");
            }
            return Colors.Black;
        }

        /// <summary>
        /// 从全局配置中获取文字标注的颜色
        /// </summary>
        /// <returns>文字标注的颜色，如果无法获取配置则返回默认颜色</returns>
        private Color GetAnnotationColorFromConfig()
        {
            try
            {
                // 尝试从全局配置中获取印字层颜色
                var configService = (IGlobalConfigService)Prism.Ioc.ContainerLocator.Container?.Resolve(typeof(IGlobalConfigService));
                if (configService != null)
                {
                    // 使用同步方式获取配置，避免异步操作复杂性
                    var colorConfigTask = Task.Run(async () =>
                    {
                        try
                        {
                            using (var cts = new System.Threading.CancellationTokenSource(TimeSpan.FromSeconds(5)))
                            {
                                return await configService.GetLayerColorConfigAsync().ConfigureAwait(false);
                            }
                        }
                        catch (OperationCanceledException)
                        {
                            System.Diagnostics.Debug.WriteLine("获取图层颜色配置超时，使用默认颜色");
                            return new LayerColorConfig();
                        }
                        catch (Exception ex)
                        {
                            System.Diagnostics.Debug.WriteLine($"获取图层颜色配置失败: {ex.Message}");
                            return new LayerColorConfig();
                        }
                    });

                    // 等待任务完成，但设置较短的超时时间
                    if (colorConfigTask.Wait(TimeSpan.FromSeconds(8)))
                    {
                        var colorConfig = colorConfigTask.Result;
                        var hexColor = colorConfig.TextLayerColor;
                        if (!string.IsNullOrEmpty(hexColor))
                        {
                            var configColor = HexToColor(hexColor);
                            System.Diagnostics.Debug.WriteLine($"从全局配置获取到印字层颜色: {hexColor} -> {configColor}");
                            return configColor;
                        }
                    }
                    else
                    {
                        System.Diagnostics.Debug.WriteLine("获取图层颜色配置超时，使用默认颜色");
                    }
                }
                else
                {
                    System.Diagnostics.Debug.WriteLine("无法获取全局配置服务，使用默认颜色");
                }
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine($"获取文字标注颜色时发生异常: {ex.Message}");
            }

            // 如果无法获取配置，返回默认的印字层颜色（橙色）
            System.Diagnostics.Debug.WriteLine("使用默认印字层颜色: Orange");
            return Colors.Orange;
        }

        /// <summary>
        /// 获取当前鼠标交互灵敏度设置
        /// </summary>
        /// <returns>包含旋转和调整大小手柄扩展像素的元组</returns>
        public (double rotateExpansion, double resizeExpansion) GetMouseInteractionSensitivity()
        {
            return (_rotateHandleExpansion, _resizeHandleExpansion);
        }

        /// <summary>
        /// 检查3D世界坐标点是否在当前视口的可视区域内
        /// </summary>
        /// <param name="worldPosition">3D世界坐标点</param>
        /// <param name="margin">边距（像素），用于增加检测的容错性</param>
        /// <returns>是否在可视区域内</returns>
        private bool IsPointInViewport(Point3D worldPosition, double margin = 50)
        {
            try
            {
                // 将3D世界坐标转换为屏幕坐标
                var screenPoint = Point3DToScreen(worldPosition);
                
                // 使用统一的视口边界计算，但添加更大的边距
                var viewportBounds = GetActualViewportBounds();
                
                // 添加更大的边距，使判断更加宽松
                var expandedBounds = new Rect(
                    viewportBounds.X - margin,
                    viewportBounds.Y - margin,
                    viewportBounds.Width + margin * 2,
                    viewportBounds.Height + margin * 2
                );
                
                return expandedBounds.Contains(screenPoint);
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine($"检查视口可见性失败: {ex.Message}");
                return false;
            }
        }

        /// <summary>
        /// 检查编辑框是否应该显示（基于当前选中文字的位置）
        /// </summary>
        /// <returns>是否应该显示编辑框</returns>
        private bool ShouldShowEditBox()
        {
            if (_selectedTextInfo == null) return false;
            
            // 检查选中文字的位置是否在视口内，使用更大的边距使判断更宽松
            return IsPointInViewport(_selectedTextInfo.Position, 150);
        }

        /// <summary>
        /// 检查编辑框的完整边界是否在视口内
        /// </summary>
        /// <param name="editRect">编辑框矩形（可选，如果不提供则使用当前编辑框）</param>
        /// <returns>编辑框是否完全在视口内</returns>
        private bool IsEditBoxInViewport(Rect? editRect = null)
        {
            try
            {
                Rect rectToCheck;
                
                if (editRect.HasValue)
                {
                    // 使用提供的编辑框矩形
                    rectToCheck = editRect.Value;
                }
                else if (_textEditAdorner != null)
                {
                    // 使用当前编辑框的边界矩形
                    rectToCheck = _textEditAdorner.EditRect;
                }
                else
                {
                    return false;
                }
                
                // 获取视口边界（不包含标题栏区域）
                var viewportBounds = GetActualViewportBounds();
                
                // 检查编辑框是否完全在视口内
                return viewportBounds.Contains(rectToCheck);
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine($"检查编辑框边界失败: {ex.Message}");
                return false;
            }
        }

        /// <summary>
        /// 获取实际可用的视口边界（排除标题栏等UI元素）
        /// </summary>
        /// <returns>实际可用的视口边界</returns>
        private Rect GetActualViewportBounds()
        {
            // 获取控件的实际尺寸
            var controlBounds = new Rect(0, 0, this.ActualWidth, this.ActualHeight);
            
            // 简单设置标题栏高度，避免复杂的计算
            var titleBarHeight = 80; // 固定值，从图片观察约为80像素
            var availableHeight = Math.Max(0, controlBounds.Height - titleBarHeight);
            
            // 返回可用的视口区域
            return new Rect(0, titleBarHeight, controlBounds.Width, availableHeight);
        }



        /// <summary>
        /// 检查并尝试重新显示因视口原因被隐藏的编辑框
        /// </summary>
        public void CheckAndRestoreEditBox()
        {
            if (_selectedTextInfo != null && _editBoxWasHiddenDueToViewport && !_isEditBoxVisible)
            {
                if (IsPointInViewport(_selectedTextInfo.Position, 150))
                {
                    // 文字重新进入视口，恢复编辑框
                    AddEditHandles(_selectedTextInfo);
                    _isEditBoxVisible = true;
                    _editBoxWasHiddenDueToViewport = false;
                    System.Diagnostics.Debug.WriteLine("编辑框已恢复：文字重新进入视口");
                }
            }
        }

        /// <summary>
        /// 测试鼠标位置是否在旋转手柄区域内
        /// </summary>
        /// <param name="mousePos">鼠标位置</param>
        /// <returns>是否在旋转手柄区域内</returns>
        public bool IsMouseOverRotateHandle(Point mousePos)
        {
            return GetRotateHandleRect().Contains(mousePos);
        }

        /// <summary>
        /// 测试鼠标位置是否在调整大小手柄区域内
        /// </summary>
        /// <param name="mousePos">鼠标位置</param>
        /// <returns>手柄索引，如果不在任何手柄区域内则返回-1</returns>
        public int GetResizeHandleIndex(Point mousePos)
        {
            var handleRects = GetHandleRects();
            for (int i = 0; i < handleRects.Length; i++)
            {
                if (handleRects[i].Contains(mousePos))
                {
                    return i;
                }
            }
            return -1;
        }

        /// <summary>
        /// 显示编辑提示信息
        /// </summary>
        /// <param name="message">提示信息</param>
        /// <param name="position">显示位置</param>
        /// <param name="duration">显示时长（毫秒）</param>
        public void ShowEditTip(string message, Point position, int duration = 2000)
        {
            var tip = new System.Windows.Controls.TextBlock
            {
                Text = message,
                Background = System.Windows.Media.Brushes.Black,
                Foreground = System.Windows.Media.Brushes.White,
                Padding = new System.Windows.Thickness(8, 4, 8, 4),
                FontSize = 12,
                Effect = new System.Windows.Media.Effects.DropShadowEffect
                {
                    Color = System.Windows.Media.Colors.Black,
                    Direction = 315,
                    ShadowDepth = 2,
                    Opacity = 0.5,
                    BlurRadius = 3
                }
            };

            // 查找overlayCanvas
            var parentPanel = this.Parent as System.Windows.Controls.Panel ?? System.Windows.Media.VisualTreeHelper.GetParent(this) as System.Windows.Controls.Panel;
            System.Windows.Controls.Canvas overlay = null;
            foreach (var child in parentPanel.Children)
            {
                if (child is System.Windows.Controls.Canvas c && c.Name == "overlayCanvas")
                {
                    overlay = c;
                    break;
                }
            }
            if (overlay == null) return;

            overlay.Children.Add(tip);
            System.Windows.Controls.Canvas.SetLeft(tip, position.X);
            System.Windows.Controls.Canvas.SetTop(tip, position.Y);
            System.Windows.Controls.Panel.SetZIndex(tip, 1001); // 比编辑框更高层级

            // 定时移除提示
            var timer = new System.Windows.Threading.DispatcherTimer
            {
                Interval = TimeSpan.FromMilliseconds(duration)
            };
            timer.Tick += (s, e) =>
            {
                overlay.Children.Remove(tip);
                timer.Stop();
            };
            timer.Start();
        }


        public AnnotationDisplayerControl()
        {
            System.Diagnostics.Debug.WriteLine($"=== AnnotationDisplayerControl构造函数 ===");
            System.Diagnostics.Debug.WriteLine($"控件类型: {this.GetType().Name}");
            System.Diagnostics.Debug.WriteLine($"当前ControlId: '{this.ControlId ?? "null"}'");

            // 镜像变换管理器将在ControlId设置后延迟初始化

            // 使用新的字段名称  
            this._eventAggregatorInstance = (IEventAggregator)Prism.Ioc.ContainerLocator.Container.Resolve(typeof(IEventAggregator));

            this.Loaded += AnnotationDisplayerControl_Loaded;
            this.CameraChanged += OnCameraChanged;

            this._eventAggregatorInstance.GetEvent<UpdateLayerSpecEntity>()
                .Subscribe((tuple) => { if (tuple.ControlId == this.ControlId) OnUpdateLayerSpecEntity(tuple.LayeredEntityList); }, ThreadOption.UIThread);

            this._eventAggregatorInstance.GetEvent<DisplayDxfPart>()
                .Subscribe((tuple) =>
                {
                    if (tuple.ControlId == this.ControlId)
                    {
                        // 注册视口到相机同步管理器
                        if (!string.IsNullOrEmpty(this.ControlId))
                        {
                            try
                            {
                                this.RegisterForCameraSync(this.ControlId);
                                System.Diagnostics.Debug.WriteLine($"视口注册到相机同步管理器成功: {this.ControlId}");
                            }
                            catch (Exception ex)
                            {
                                System.Diagnostics.Debug.WriteLine($"视口注册到相机同步管理器失败: {ex.Message}");
                            }
                        }
                        else
                        {
                            System.Diagnostics.Debug.WriteLine("控件ID为空，无法注册到相机同步管理器");
                        }

                        // 检查是否有映射关系
                        if (tuple.HandleMapping != null && tuple.HandleMapping.Count > 0)
                        {
                            DisplayDxfDocumentPartWithMapping(tuple);
                        }
                        else
                        {
                            DisplayDxfDocumentPart(tuple.Document);
                        }
                    }
                }, ThreadOption.UIThread);

            this._eventAggregatorInstance.GetEvent<DisplayDxfPartList>()
                .Subscribe((tuple) =>
                {
                    if (tuple.ControlId == this.ControlId)
                    {
                        // 注册视口到相机同步管理器
                        if (!string.IsNullOrEmpty(this.ControlId))
                        {
                            try
                            {
                                this.RegisterForCameraSync(this.ControlId);
                                System.Diagnostics.Debug.WriteLine($"视口注册到相机同步管理器成功: {this.ControlId}");
                            }
                            catch (Exception ex)
                            {
                                System.Diagnostics.Debug.WriteLine($"视口注册到相机同步管理器失败: {ex.Message}");
                            }
                        }
                        else
                        {
                            System.Diagnostics.Debug.WriteLine("控件ID为空，无法注册到相机同步管理器");
                        }

                        DisplayDxfDocumentPartList(tuple.Documents);
                    }
                }, ThreadOption.UIThread);

            this._eventAggregatorInstance.GetEvent<UpdateLayersInfo>()
                .Subscribe((tuple) => { if (tuple.ControlId == this.ControlId) OnUpdateLayerSpecEntity(new LayeredEntityList(tuple.DocumentName, new List<netDxf.Entities.EntityObject>())); }, ThreadOption.UIThread);

            this.MouseLeftButtonDown += helixView_MouseDown;
            this.MouseMove += helixView_MouseMove;
            this.MouseRightButtonDown += helixView_MouseRightDown;
            this.MouseLeftButtonUp += helixView_MouseUp;

            this._eventAggregatorInstance.GetEvent<EditAnnotationEvent>()
                .Subscribe((tuple) =>
                {
                    if (tuple.ControlId == this.ControlId)
                        OnEditAnnotation(tuple.Mode);
                }, ThreadOption.UIThread);

            this._eventAggregatorInstance.GetEvent<ApplyTextEditEvent>()
                .Subscribe(args => { if (args.ControlId == this.ControlId) OnApplyTextEdit(args.EditInfo); }, ThreadOption.UIThread);

            this._eventAggregatorInstance.GetEvent<CancelTextEditEvent>()
                .Subscribe((evtControlId) => { if (evtControlId == this.ControlId) OnCancelTextEdit(); }, ThreadOption.UIThread);

            this._eventAggregatorInstance.GetEvent<DeleteTextEditEvent>()
                .Subscribe((evtControlId) => { if (evtControlId == this.ControlId) OnDeleteTextEdit(); }, ThreadOption.UIThread);

            // ✅ 新增：订阅清理缓存事件
            this._eventAggregatorInstance.GetEvent<ClearAnnotationCacheEvent>()
                .Subscribe(args => OnClearAnnotationCache(args), ThreadOption.UIThread);

            // 订阅镜像同步事件
            this._eventAggregatorInstance.GetEvent<MirrorSyncEvent>()
                .Subscribe(OnMirrorSync, ThreadOption.UIThread);

            // 订阅同步到DXF事件
            this._eventAggregatorInstance.GetEvent<SyncToDxfEvent>()
                .Subscribe(args =>
                {
                    if (args != null)
                        SyncAllTextInfoToDxf();
                }, ThreadOption.UIThread);

            // 添加事件订阅调试信息
            System.Diagnostics.Debug.WriteLine($"=== 事件订阅调试信息 ===");
            System.Diagnostics.Debug.WriteLine($"控件ID: {this.ControlId}");
            System.Diagnostics.Debug.WriteLine($"事件聚合器: {_eventAggregatorInstance != null}");
            System.Diagnostics.Debug.WriteLine($"镜像同步事件订阅完成");
            System.Diagnostics.Debug.WriteLine($"同步到DXF事件订阅完成");
            System.Diagnostics.Debug.WriteLine($"=== AnnotationDisplayerControl构造函数完成 ===");
        }

        private void OnEditAnnotation(EditingMode mode)
        {
            if (_currentEditingMode != mode)
            {
                _currentEditingMode = mode;
                OnEditAnnotationChanged();
            }
        }

        /// <summary>
        /// 编辑模式发生变化时的处理逻辑
        /// </summary>
        private void OnEditAnnotationChanged()
        {
            // 当编辑模式改变时，移除当前的编辑框
            RemoveCurrentEditAdorner();

            // 如果退出编辑模式或新增模式，移除编辑手柄
            if (_currentEditingMode != EditingMode.Editing && _currentEditingMode != EditingMode.Adding)
            {
                RemoveEditHandles();
            }
            // 如果进入编辑模式且有选中的文字，显示编辑手柄
            else if (_currentEditingMode == EditingMode.Editing && _selectedTextInfo != null)
            {
                AddEditHandles(_selectedTextInfo);
            }
        }

        /// <summary>
        /// 处理应用文字编辑事件
        /// </summary>
        /// <param name="editInfo">编辑信息</param>
        private void OnApplyTextEdit(TextEditInfo editInfo)
        {
            if (editInfo == null || _selectedTextInfo == null)
                return;

            // 更新文字信息
            _selectedTextInfo.Text = editInfo.Text;
            _selectedTextInfo.Color = editInfo.Color;
            _selectedTextInfo.Height = editInfo.Height;
            _selectedTextInfo.Underline = editInfo.Underline;

            // ✅ 关键修复：同步更新DXF文档中的实体
            SyncTextInfoToDxfEntity(_selectedTextInfo);

            // 更新文字视觉对象
            UpdateTextVisual(_selectedTextInfo);

            // 同步编辑辅助元素
            AddEditHandles(_selectedTextInfo);

        }

        /// <summary>
        /// 处理取消文字编辑事件
        /// </summary>
        private void OnCancelTextEdit()
        {
            // 移除ShowTextEditPanel相关代码
        }

        /// <summary>
        /// 处理清理标注缓存事件
        /// 当切换图纸时，清理所有内部缓存和映射数据
        /// </summary>
        private void OnClearAnnotationCache(ClearAnnotationCacheEventArgs args)
        {
            System.Diagnostics.Debug.WriteLine($"=== 控件 {this.ControlId} 开始清理缓存 ===");
            System.Diagnostics.Debug.WriteLine($"清理原因: {args.Reason}");
            
            try
            {
                // 清理文字信息映射
                _textInfoMap.Clear();
                System.Diagnostics.Debug.WriteLine($"已清理 _textInfoMap，数量: {_textInfoMap.Count}");
                
                // 清理实体视觉映射
                _entityVisualMap.Clear();
                System.Diagnostics.Debug.WriteLine($"已清理 _entityVisualMap，数量: {_entityVisualMap.Count}");
                
                // 清理Handle映射关系
                _handleMapping.Clear();
                _reverseHandleMapping.Clear();
                System.Diagnostics.Debug.WriteLine($"已清理Handle映射关系");
                
                // 清理实体映射关系
                _entityMapping.Clear();
                System.Diagnostics.Debug.WriteLine($"已清理实体映射关系");
                
                // 清理选中状态
                ClearTextSelection();
                System.Diagnostics.Debug.WriteLine($"已清理选中状态");
                
                // 清理当前DXF文档引用
                _currentDxfDocument = null;
                System.Diagnostics.Debug.WriteLine($"已清理当前DXF文档引用");
                
                // 清理预览模式状态
                _isInPreviewMode = false;
                _previewAnnotationId = null;
                _previewTextVisual = null;
                System.Diagnostics.Debug.WriteLine($"已清理预览模式状态");
                
                // 清理编辑模式状态
                _currentEditingMode = EditingMode.None;
                System.Diagnostics.Debug.WriteLine($"已清理编辑模式状态");
                
                // 清理编辑手柄
                RemoveEditHandles();
                System.Diagnostics.Debug.WriteLine($"已清理编辑手柄");
                
                // 清理当前编辑框
                RemoveCurrentEditAdorner();
                System.Diagnostics.Debug.WriteLine($"已清理当前编辑框");
                
                // 清理3D场景中的标注模型
                foreach (var layerModel in _annotationModels.Values)
                {
                    layerModel.Children.Clear();
                }
                _annotationModels.Clear();
                System.Diagnostics.Debug.WriteLine($"已清理3D场景中的标注模型");
                
                // 重置边界值
                ResetBoundaries();
                System.Diagnostics.Debug.WriteLine($"已重置边界值");
                
                System.Diagnostics.Debug.WriteLine($"=== 控件 {this.ControlId} 缓存清理完成 ===");
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine($"控件 {this.ControlId} 清理缓存时发生异常: {ex.Message}");
                System.Diagnostics.Debug.WriteLine($"异常堆栈: {ex.StackTrace}");
            }
        }

        /// <summary>
        /// 显示DXF文档的内容
        /// </summary>
        /// <param name="document"></param>
        private void DisplayDxfDocumentPart(DxfDocument document)
        {
            if (document == null) return;

            // 设置当前DXF文档引用
            SetCurrentDxfDocument(document);

            // 清空文字信息映射
            _textInfoMap.Clear();
            _entityVisualMap.Clear();
            ClearTextSelection();

            // 按图层分组实体  
            var layerGroups = document.Entities.All
                .GroupBy(e => e.Layer?.Name ?? "Default")
                .ToList();

            foreach (var group in layerGroups)
            {
                var layeredEntities = group.ToList();
                if (layeredEntities.Count == 0) continue;

                // 组装LayeredEntityList，重用OnUpdateLayerSpecEntity逻辑  
                var layeredEntityList = new LayeredEntityList(group.Key, layeredEntities);
                OnUpdateLayerSpecEntity(layeredEntityList);
            }
        }

        /// <summary>
        /// 显示DXF文档的内容（带映射关系）
        /// </summary>
        /// <param name="args">包含文档和映射关系的事件参数</param>
        private void DisplayDxfDocumentPartWithMapping(DisplayDxfPartArgs args)
        {
            if (args?.Document == null) return;

            // 设置当前DXF文档引用
            SetCurrentDxfDocument(args.Document);

            // 清空文字信息映射
            _textInfoMap.Clear();
            _entityVisualMap.Clear();
            ClearTextSelection();

            // 清空并重新建立映射关系
            _handleMapping.Clear();
            _reverseHandleMapping.Clear();
            _entityMapping.Clear();

            // 建立Handle映射关系
            if (args.HandleMapping != null)
            {
                foreach (var kvp in args.HandleMapping)
                {
                    _handleMapping[kvp.Key] = kvp.Value;
                    _reverseHandleMapping[kvp.Value] = kvp.Key;
                    System.Diagnostics.Debug.WriteLine($"建立Handle映射: {kvp.Key} -> {kvp.Value}");
                }
            }

            // 建立实体映射关系
            if (args.EntityMapping != null)
            {
                foreach (var kvp in args.EntityMapping)
                {
                    _entityMapping[kvp.Key] = kvp.Value;
                }
            }

            // 按图层分组实体  
            var layerGroups = args.Document.Entities.All
                .GroupBy(e => e.Layer?.Name ?? "Default")
                .ToList();

            foreach (var group in layerGroups)
            {
                var layeredEntities = group.ToList();
                if (layeredEntities.Count == 0) continue;

                // 组装LayeredEntityList，重用OnUpdateLayerSpecEntity逻辑  
                var layeredEntityList = new LayeredEntityList(group.Key, layeredEntities);
                OnUpdateLayerSpecEntity(layeredEntityList);
            }

            System.Diagnostics.Debug.WriteLine($"镜像文档加载完成，Handle映射数量: {_handleMapping.Count}");
        }

        private void DisplayDxfDocumentPartList(List<DxfDocument> documents)
        {
            // 清空文字信息映射
            _textInfoMap.Clear();
            _entityVisualMap.Clear();
            ClearTextSelection();

            foreach (var oneDoc in documents)
            {
                // 按图层分组实体  
                var layerGroups = oneDoc.Entities.All
                    .GroupBy(e => e.Layer?.Name ?? "Default")
                    .ToList();

                foreach (var group in layerGroups)
                {
                    var layeredEntities = group.ToList();
                    if (layeredEntities.Count == 0) continue;

                    // 组装LayeredEntityList，重用OnUpdateLayerSpecEntity逻辑  
                    var layeredEntityList = new LayeredEntityList(group.Key, layeredEntities);
                    OnUpdateLayerSpecEntity(layeredEntityList);
                }
            }

        }

        /// <summary>
        /// 同步单个TextInfo到DXF实体
        /// </summary>
        /// <param name="textInfo">要同步的TextInfo</param>
        private void SyncTextInfoToDxfEntity(TextInfo textInfo)
        {
            if (textInfo == null || _currentDxfDocument == null)
                return;

            try
            {
                // 通过Id找到对应的DXF实体
                // Id格式为 "Text_{handle}" 或 "MText_{handle}"
                if (textInfo.Id != null && textInfo.Id.Contains("_"))
                {
                    string[] parts = textInfo.Id.Split('_');
                    if (parts.Length == 2)
                    {
                        string handle = parts[1];
                        var entity = _currentDxfDocument.Entities.All.FirstOrDefault(e => e.Handle == handle);

                        if (entity is Text textEntity)
                        {
                            // 更新DXF实体的属性
                            textEntity.Value = textInfo.Text;
                            textEntity.Position = new Vector3(textInfo.Position.X, textInfo.Position.Y, textInfo.Position.Z);
                            textEntity.Rotation = textInfo.Rotation;
                            textEntity.Height = textInfo.Height;

                            // 更新颜色
                            if (textInfo.Color != null)
                            {
                                textEntity.Color = netDxf.AciColor.FromTrueColor(
                                    System.Drawing.Color.FromArgb(textInfo.Color.A, textInfo.Color.R, textInfo.Color.G, textInfo.Color.B).ToArgb());
                            }

                            System.Diagnostics.Debug.WriteLine($"已同步TextInfo到DXF实体: {textInfo.Id} -> {textEntity.Handle}");
                        }
                        else if (entity is MText mTextEntity)
                        {
                            // 更新MText实体的属性
                            mTextEntity.Value = textInfo.Text;
                            mTextEntity.Position = new Vector3(textInfo.Position.X, textInfo.Position.Y, textInfo.Position.Z);
                            mTextEntity.Rotation = textInfo.Rotation;
                            mTextEntity.Height = textInfo.Height;

                            // 更新颜色
                            if (textInfo.Color != null)
                            {
                                mTextEntity.Color = netDxf.AciColor.FromTrueColor(
                                    System.Drawing.Color.FromArgb(textInfo.Color.A, textInfo.Color.R, textInfo.Color.G, textInfo.Color.B).ToArgb());
                            }

                            System.Diagnostics.Debug.WriteLine($"已同步TextInfo到MText实体: {textInfo.Id} -> {mTextEntity.Handle}");
                        }
                    }
                }
                else
                {
                    System.Diagnostics.Debug.WriteLine($"警告：TextInfo的Id格式不正确: {textInfo.Id}");
                }
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine($"同步TextInfo到DXF实体时发生错误: {ex.Message}");
            }
        }

        /// <summary>
        /// 同步所有TextInfo到DXF文档
        /// </summary>
        private void SyncAllTextInfoToDxf()
        {
            if (_currentDxfDocument == null)
                return;

            try
            {
                int syncCount = 0;
                foreach (var kvp in _textInfoMap)
                {
                    var textInfo = kvp.Value;
                    if (textInfo != null)
                    {
                        SyncTextInfoToDxfEntity(textInfo);
                        syncCount++;
                    }
                }

                System.Diagnostics.Debug.WriteLine($"已同步 {syncCount} 个TextInfo到DXF文档: {_currentDxfDocument.Name}");
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine($"同步所有TextInfo到DXF文档时发生错误: {ex.Message}");
            }
        }


        /// <summary>
        /// 将DXF实体转换为3D视觉元素
        /// </summary>
        /// <param name="entity">DXF实体</param>
        /// <returns>转换后的3D视觉元素</returns>
        private ModelVisual3D ConvertEntityToVisual(EntityObject entity)
        {
            if (entity == null)
                return null;

            switch (entity)
            {
                case Line line:
                    bool isContinuous;
                    var dashStyle = GetLineDashStyle(line, out isContinuous);
                    if (isContinuous)
                    {
                        return CreateContinuousLinesVisual(
                            new List<Point3D>
                            {
                                new Point3D(line.StartPoint.X, line.StartPoint.Y, line.StartPoint.Z),
                                new Point3D(line.EndPoint.X, line.EndPoint.Y, line.EndPoint.Z)
                            },
                            ConvertDxfColor(line.Color, line.Layer),
                            1
                        );
                    }
                    else
                    {
                        return CreateDashedVisual(
                            new List<Point3D>
                            {
                                new Point3D(line.StartPoint.X, line.StartPoint.Y, line.StartPoint.Z),
                                new Point3D(line.EndPoint.X, line.EndPoint.Y, line.EndPoint.Z)
                            },
                            dashStyle,
                            ConvertDxfColor(line.Color, line.Layer),
                            1
                        );
                    }

                case Circle circle:
                    return GetCircleVisual(circle);
                case Arc arc:
                    return GetArcVisual(arc);
                case Text text:
                    var textValue = text.Value.Replace("%", "");
                    var color = ConvertDxfColor(text.Color, text.Layer);
                    var originalPosition = new Point3D(text.Position.X, text.Position.Y, text.Position.Z);

                    // 使用镜像变换管理器创建视觉对象（自动处理镜像变换，对外部透明）
                    var textVisual = GetMirrorTransformManager().CreateMirrorTextVisual(
                        textValue, new SolidColorBrush(color), true, text.Height,
                        originalPosition, text.Rotation, "Cascadia Code", false, text.Rotation);

                    // 为文字添加唯一标识和信息
                    string textId = $"Text_{text.Handle}";
                    textVisual.SetValue(FrameworkElement.TagProperty, textId);

                    // 添加到实体视觉映射表
                    _entityVisualMap[textId] = textVisual;

                    // 获取实际的镜像位置和角度（从镜像变换管理器）
                    var actualPosition = GetMirrorTransformManager().IsMirrorControl ?
                        GetMirrorTransformManager().TransformPosition(originalPosition, text.Rotation, text.Height) :
                        originalPosition;
                    var actualRotation = GetMirrorTransformManager().IsMirrorControl ?
                        GetMirrorTransformManager().TransformRotation(text.Rotation) :
                        text.Rotation;

                    _textInfoMap[textId] = new TextInfo
                    {
                        Id = textId,
                        Text = textValue,
                        Position = actualPosition,
                        Height = text.Height,
                        Rotation = actualRotation,
                        LayerName = text.Layer?.Name ?? "Default",
                        Color = color,
                        Underline = false, // 默认无下划线
                        OriginalEntity = text
                    };
                    return textVisual;
                case MText mText:
                    var lines = mText.Value.Split(new[] { "\\P" }, StringSplitOptions.None);
                    var basePointCad = new Point3D(mText.Position.X, mText.Position.Y, mText.Position.Z);
                    double lineSpacing = mText.Height * mText.LineSpacingFactor;

                    var basePointWpf = AdjustBasePointForAlignment(
                        mText.AttachmentPoint,
                        basePointCad,
                        mText.RectangleWidth > 0 ? mText.RectangleWidth : lines.Length * mText.Height + (lines.Length - 1) * lineSpacing,
                        mText.Height
                    );

                    // 创建容器来存储多行文本
                    //todo: refine 当前仅考虑单行文本的情况
                    //var container = new ModelVisual3D();
                    ModelVisual3D mTextVisual = null;
                    for (int i = 0; i < lines.Length; i++)
                    {
                        var lineText = lines[i];
                        var lineBasePoint = basePointCad - new Vector3D(0, i * lineSpacing, 0);

                        //// 使用镜像变换管理器处理位置和旋转
                        //var mDestPos = GetMirrorTransformManager().TransformPosition(lineBasePoint, mText.Rotation, mText.Height);
                        //var mDestRotation = GetMirrorTransformManager().TransformRotation(mText.Rotation);

                        // 使用镜像变换管理器创建视觉对象
                        mTextVisual = GetMirrorTransformManager().CreateMirrorMTextVisual(
                            lineText, new SolidColorBrush(ConvertDxfColor(mText.Color, mText.Layer)),
                            true, mText.Height, lineBasePoint, mText.Rotation,
                            basePointWpf - basePointCad, "Cascadia Code", false);

                        // 获取实际的镜像位置和角度（从镜像变换管理器）
                        var actualMTextPosition = GetMirrorTransformManager().IsMirrorControl ?
                        GetMirrorTransformManager().TransformPosition(lineBasePoint, mText.Rotation, mText.Height) :
                            lineBasePoint;
                        var actualMTextRotation = GetMirrorTransformManager().IsMirrorControl ?
                            GetMirrorTransformManager().TransformRotation(mText.Rotation) :
                            mText.Rotation;

                        if (mTextVisual != null)
                        {
                            // 为每行文字添加唯一标识和信息
                            //TODO: 待改进：由于 MText 可能包含多行文本，暂时仅考虑1行的情况
                            string mTextId = $"MText_{mText.Handle}";
                            mTextVisual.SetValue(FrameworkElement.TagProperty, mTextId);

                            // 添加到实体视觉映射表
                            _entityVisualMap[mTextId] = mTextVisual;

                            _textInfoMap[mTextId] = new TextInfo
                            {
                                Id = mTextId,
                                Text = lineText,
                                Position = actualMTextPosition,
                                Height = mText.Height,
                                Rotation = actualMTextRotation,
                                LayerName = mText.Layer?.Name ?? "Default",
                                Color = ConvertDxfColor(mText.Color, mText.Layer),
                                Underline = false, // 默认无下划线
                                OriginalEntity = mText
                            };

                            //仅考虑单行文本的情况
                            //container.Children.Add(mTextVisual);
                        }
                    }
                    return mTextVisual;
                case Ellipse ellipse:
                    return GetEllipseVisual(ellipse);

                default:
                    return null;
            }
        }



        /// <summary>
        /// 计算从当前角度逆时针旋转到目标角度所需的角度值（0-360）
        /// </summary>
        /// <param name="fromAngle">起始角度（可正可负，可大于360）</param>
        /// <param name="toAngle">目标角度（可正可负，可大于360）</param>
        /// <returns>逆时针旋转的角度（范围 0 ~ 360）</returns>
        public static double GetCCWAngle(double fromAngle, double toAngle)
        {
            // 1. 把角度统一到 0 ~ 360 之间
            double start = ((fromAngle % 360) + 360) % 360;
            double end = ((toAngle % 360) + 360) % 360;

            // 2. 计算逆时针差值
            double ccw = (end - start + 360) % 360;

            return ccw;
        }


        /// <summary>
        /// 清除文字选中状态
        /// </summary>
        private void ClearTextSelection()
        {
            SetTextHighlight(false);
            if (_selectedTextVisual != null && _originalMaterial != null)
            {
                var geometryModel = _selectedTextVisual.Content as GeometryModel3D;
                if (geometryModel != null)
                {
                    geometryModel.Material = _originalMaterial;
                }
                _selectedTextVisual = null;
                _originalMaterial = null;
                _selectedTextId = null;
                _selectedTextInfo = null; // 清理选中的文字信息
            }
            RemoveEditHandles();
            
            // 重置编辑框可见性状态
            _isEditBoxVisible = false;
            _editBoxWasHiddenDueToViewport = false;
        }

        /// <summary>
        /// 高亮显示选中的文字
        /// </summary>
        /// <param name="textVisual">要高亮的文字视觉对象</param>
        private void HighlightSelectedText(ModelVisual3D textVisual)
        {
            var geometryModel = textVisual.Content as GeometryModel3D;
            if (geometryModel != null)
            {
                _originalMaterial = geometryModel.Material;
                _selectedTextVisual = textVisual;
                SetTextHighlight(true);
            }
        }

        /// <summary>
        /// 检查是否为文字视觉对象
        /// </summary>
        /// <param name="visual">要检查的视觉对象</param>
        /// <returns>是否为文字对象</returns>
        private bool IsTextVisual(ModelVisual3D visual)
        {
            if (visual == null) return false;

            var tag = visual.GetValue(FrameworkElement.TagProperty) as string;
            return !string.IsNullOrEmpty(tag) && (tag.StartsWith("Text_") || tag.StartsWith("MText_")) && _textInfoMap.ContainsKey(tag);
        }

        /// <summary>
        /// 处理文字选中
        /// </summary>
        /// <param name="textVisual">选中的文字视觉对象</param>
        private void HandleTextSelection(ModelVisual3D textVisual)
        {
            if (_currentEditingMode != EditingMode.Editing)
                return;

            var tag = textVisual.GetValue(FrameworkElement.TagProperty) as string;
            if (string.IsNullOrEmpty(tag)) return;

            // If a different text is clicked, clear the previous selection.
            if (_selectedTextVisual != textVisual)
            {
                ClearTextSelection();
            }

            // Highlight the new selection
            HighlightSelectedText(textVisual);
            _selectedTextId = tag;

            // Show the adorner for the newly selected text (only in editing mode)
            TextInfo textInfo = null;

            // 策略1：直接从_textInfoMap查找
            if (_textInfoMap.TryGetValue(tag, out textInfo))
            {
                // 找到文字信息
            }
            // 策略2：通过镜像映射查找
            else if (_handleMapping.ContainsKey(tag) && _textInfoMap.TryGetValue(_handleMapping[tag], out textInfo))
            {
                // 通过镜像映射找到文字信息
                System.Diagnostics.Debug.WriteLine($"通过镜像映射找到文字信息: {tag} -> {_handleMapping[tag]}");
            }
            // 策略3：通过反向映射查找
            else if (_reverseHandleMapping.ContainsKey(tag) && _textInfoMap.TryGetValue(_reverseHandleMapping[tag], out textInfo))
            {
                // 通过反向映射找到文字信息
                System.Diagnostics.Debug.WriteLine($"通过反向映射找到文字信息: {tag} -> {_reverseHandleMapping[tag]}");
            }
            // 策略4：通过全局镜像映射管理器查找（与编辑/删除操作保持一致）
            else if (this.ControlId == "normal")
            {
                // 当前是normal控件，尝试查找镜像实体的文字信息
                string originalDocumentName = GetOriginalDocumentName(_currentDxfDocument?.Name);
                if (!string.IsNullOrEmpty(originalDocumentName))
                {
                    var mirroredHandle = MirrorEntityMappingManager.GetMirroredHandle(originalDocumentName, tag);
                    if (!string.IsNullOrEmpty(mirroredHandle) && _textInfoMap.TryGetValue(mirroredHandle, out textInfo))
                    {
                        System.Diagnostics.Debug.WriteLine($"通过全局映射管理器找到镜像实体文字信息: {tag} -> {mirroredHandle}");
                    }
                }
            }
            else if (this.ControlId == "mirror")
            {
                // 当前是mirror控件，尝试查找原始实体的文字信息
                string documentName = _currentDxfDocument?.Name;
                if (!string.IsNullOrEmpty(documentName))
                {
                    var originalHandle = MirrorEntityMappingManager.GetOriginalHandle(documentName, tag);
                    if (!string.IsNullOrEmpty(originalHandle) && _textInfoMap.TryGetValue(originalHandle, out textInfo))
                    {
                        System.Diagnostics.Debug.WriteLine($"通过全局映射管理器找到原始实体文字信息: {tag} -> {originalHandle}");
                    }
                }
            }

            if (textInfo != null)
            {
                _selectedTextInfo = textInfo; // 设置当前选中的文字信息

                // 添加调试信息
                System.Diagnostics.Debug.WriteLine($"=== HandleTextSelection 调试信息 ===");
                System.Diagnostics.Debug.WriteLine($"当前控件ID: {this.ControlId}");
                System.Diagnostics.Debug.WriteLine($"tag: '{tag}'");
                System.Diagnostics.Debug.WriteLine($"textInfo.Id: '{textInfo.Id ?? "null"}'");
                System.Diagnostics.Debug.WriteLine($"textInfo.Text: '{textInfo.Text ?? "null"}'");
                System.Diagnostics.Debug.WriteLine($"_selectedTextId: '{_selectedTextId}'");
                System.Diagnostics.Debug.WriteLine($"_selectedTextInfo.Id: '{_selectedTextInfo.Id ?? "null"}'");

                // 只在编辑模式或新增模式下显示编辑手柄
                if (_currentEditingMode == EditingMode.Editing || _currentEditingMode == EditingMode.Adding)
                {
                    // 检查文字是否在视口内，决定是否显示编辑框
                    if (ShouldShowEditBox())
                    {
                        // 文字在视口内，显示编辑框
                        AddEditHandles(textInfo);
                    }
                    else
                    {
                        // 文字不在视口内，不显示编辑框但保持选中状态
                        _isEditBoxVisible = false;
                        _editBoxWasHiddenDueToViewport = true;
                        System.Diagnostics.Debug.WriteLine("选中文字超出视口，不显示编辑框");
                    }
                }
            }
            else
            {
                System.Diagnostics.Debug.WriteLine($"警告: 无法找到Tag '{tag}' 对应的文字信息");
                System.Diagnostics.Debug.WriteLine($"当前_textInfoMap中的实体数量: {_textInfoMap.Count}");
                System.Diagnostics.Debug.WriteLine($"当前_handleMapping中的映射数量: {_handleMapping.Count}");
            }
        }


        private void AddEditHandles(TextInfo textInfo)
        {
            if (textInfo == null) return;
            RemoveEditHandles(); // Clean up previous adorner if any

            // 1. 使用与 GetTextVisual 完全一致的文字尺寸计算
            // 在 GetTextVisual 中，文字宽度是通过 text.Length * height * 0.85f 计算的
            double width3D = textInfo.Text.Length * textInfo.Height * 0.85;
            double height3D = textInfo.Height; // 使用实际文字高度

            // 2. 计算文字的实际左下角位置（与 GetTextVisual 中的计算保持一致）
            // 在 GetTextVisual 中，文字左下角是通过 basePoint - up * height / 6 计算的
            Vector3D up = new Vector3D(0, 1, 0); // 假设向上方向
            Point3D actualBottomLeft = textInfo.Position - up * textInfo.Height / 6;

            // 3. 计算0度时的四个角点（以实际文字左下角为原点）
            Point3D bottomLeft = actualBottomLeft; // 实际左下角（基准点）
            Point3D topLeft = new Point3D(bottomLeft.X, bottomLeft.Y + height3D, bottomLeft.Z);
            Point3D bottomRight = new Point3D(bottomLeft.X + width3D, bottomLeft.Y, bottomLeft.Z);
            Point3D topRight = new Point3D(bottomLeft.X + width3D, bottomLeft.Y + height3D, bottomLeft.Z);

            // 4. 将0度时的角点旋转到当前角度
            double angle = textInfo.Rotation * Math.PI / 180.0;
            Point3D rotatedBottomLeft = RotatePoint(bottomLeft, textInfo.Position, angle);
            Point3D rotatedTopLeft = RotatePoint(topLeft, textInfo.Position, angle);
            Point3D rotatedBottomRight = RotatePoint(bottomRight, textInfo.Position, angle);
            Point3D rotatedTopRight = RotatePoint(topRight, textInfo.Position, angle);

            // 5. 投影到屏幕坐标
            var s0 = Point3DToScreen(rotatedBottomLeft);
            var s1 = Point3DToScreen(rotatedTopLeft);
            var s2 = Point3DToScreen(rotatedBottomRight);
            var s3 = Point3DToScreen(rotatedTopRight);

            // 6. 计算固定大小的编辑框（基于0度时的尺寸）
            // 使用0度时的屏幕投影来计算固定尺寸
            var s0_0deg = Point3DToScreen(bottomLeft);
            var s1_0deg = Point3DToScreen(topLeft);
            var s2_0deg = Point3DToScreen(bottomRight);
            var s3_0deg = Point3DToScreen(topRight);

            double fixedWidth = Math.Abs(s2_0deg.X - s0_0deg.X); // 屏幕宽度（0度时）
            double fixedHeight = Math.Abs(s1_0deg.Y - s0_0deg.Y); // 屏幕高度（0度时）

            // 7. 使用文字左下角作为旋转中心
            var textBottomLeftScreen = Point3DToScreen(actualBottomLeft);

            // 8. 计算编辑框的左上角位置（相对于文字左下角）
            // 编辑框应该以文字左下角为基准，向上和向右扩展
            // 添加一些额外的边距以确保文字完全在编辑框内
            double margin = 4.0; // 4像素的边距
            Rect editRect = new Rect(
                textBottomLeftScreen.X - margin,
                textBottomLeftScreen.Y - fixedHeight - margin,
                fixedWidth + 2 * margin,
                fixedHeight + 2 * margin);

            // 9. 检查编辑框是否在视口内，如果超出则隐藏（使用更宽松的判断）
            var viewportBounds = GetActualViewportBounds();
            
            // 扩展视口边界，使判断更加宽松
            var expandedViewportBounds = new Rect(
                viewportBounds.X - 50,  // 左边距
                viewportBounds.Y - 50,  // 上边距
                viewportBounds.Width + 100,  // 宽度增加100像素
                viewportBounds.Height + 100  // 高度增加100像素
            );
            
            if (!expandedViewportBounds.Contains(editRect))
            {
                System.Diagnostics.Debug.WriteLine("编辑框超出视口范围，不显示编辑框");
                _isEditBoxVisible = false;
                _editBoxWasHiddenDueToViewport = true;
                return;
            }

            // 10. 创建并显示Adorner
            var adornerLayer = AdornerLayer.GetAdornerLayer(this);
            if (adornerLayer != null)
            {
                _textEditAdorner = new TextEditAdorner(this)
                {
                    EditRect = editRect, // 这是未旋转的边界框
                    RotationAngle = -angle, // 旋转角度（需要与文字旋转方向一致，所以取负值）
                    RotationCenter = textBottomLeftScreen // 旋转中心为文字左下角
                };
                adornerLayer.Add(_textEditAdorner);
                _isEditBoxVisible = true;
                _editBoxWasHiddenDueToViewport = false;
            }
        }

        /// <summary>
        /// 旋转点
        /// </summary>
        /// <param name="point">要旋转的点</param>
        /// <param name="center">旋转中心</param>
        /// <param name="angle">旋转角度（弧度）</param>
        /// <returns>旋转后的点</returns>
        private Point3D RotatePoint(Point3D point, Point3D center, double angle)
        {
            double cos = Math.Cos(angle);
            double sin = Math.Sin(angle);

            double x = point.X - center.X;
            double y = point.Y - center.Y;

            double rotatedX = x * cos - y * sin;
            double rotatedY = x * sin + y * cos;

            return new Point3D(center.X + rotatedX, center.Y + rotatedY, center.Z);
        }

        /// <summary>
        /// 检测点是否在旋转的矩形内
        /// </summary>
        /// <param name="point">要检测的点</param>
        /// <param name="rect">矩形</param>
        /// <param name="angle">旋转角度（弧度）</param>
        /// <returns>如果点在旋转的矩形内返回true</returns>
        private bool IsPointInRotatedRect(Point point, Rect rect, double angle)
        {
            if (_textEditAdorner == null) return false;

            // 使用Adorner的旋转中心点
            var rotationCenter = _textEditAdorner.RotationCenter;

            // 将点转换到旋转中心的局部坐标系
            var localPoint = new Point(point.X - rotationCenter.X, point.Y - rotationCenter.Y);

            // 反向旋转点
            double cos = Math.Cos(-angle);
            double sin = Math.Sin(-angle);

            double unrotatedX = localPoint.X * cos - localPoint.Y * sin;
            double unrotatedY = localPoint.X * sin + localPoint.Y * cos;

            // 检查点是否在未旋转的矩形内
            var unrotatedPoint = new Point(unrotatedX + rotationCenter.X, unrotatedY + rotationCenter.Y);
            return rect.Contains(unrotatedPoint);
        }

        private void RemoveEditHandles()
        {
            // Remove the 2D Adorner
            if (_textEditAdorner != null)
            {
                var adornerLayer = AdornerLayer.GetAdornerLayer(this);
                adornerLayer?.Remove(_textEditAdorner);
                _textEditAdorner = null;
            }
        }


        private void OnUpdateLayerSpecEntity(LayeredEntityList layeredEntities)
        {
            if (string.IsNullOrEmpty(layeredEntities.LayerName) || layeredEntities.LayeredEntities == null || layeredEntities.LayeredEntities.Count == 0)
            {
                return; // 无效的图层或实体列表
            }

            //if (_annotationModels.ContainsKey(layeredEntities.LayerName))
            //    _annotationModels[layeredEntities.LayerName].Children.Clear(); // 清空现有的子元素

            _annotationModels[layeredEntities.LayerName] = new ModelVisual3D();

            foreach (var entity in layeredEntities.LayeredEntities)
            {
                var visualElement = ConvertEntityToVisual(entity);
                if (visualElement != null)
                {
                    _annotationModels[layeredEntities.LayerName].Children.Add(visualElement);

                    // 更新边界范围
                    UpdateBoundaries(entity);
                }
            }

            // 将新的图层模型添加到视图中
            if (!Children.Contains(_annotationModels[layeredEntities.LayerName]))
            {
                Children.Add(_annotationModels[layeredEntities.LayerName]);
            }

            // 调整相机视角
            AdjustCameraView();

            // 简单修复：确保两个视图都调用ZoomExtents()来保持一致的缩放比
            EnsureConsistentZoomLevel();
        }

        /// <summary>
        /// 确保两个视图的缩放级别一致
        /// 简单方案：两个视图都调用ZoomExtents()来保持一致的缩放比
        /// </summary>
        private void EnsureConsistentZoomLevel()
        {
            try
            {
                // 延迟执行，确保两个视图都完成加载
                System.Windows.Threading.DispatcherTimer timer = new System.Windows.Threading.DispatcherTimer();
                timer.Interval = TimeSpan.FromMilliseconds(300); // 300ms延迟，减少延迟时间
                timer.Tick += (sender, e) =>
                {
                    timer.Stop();

                    // 简单方案：直接调用ZoomExtents()确保缩放一致
                    if (this.Camera != null)
                    {
                        System.Diagnostics.Debug.WriteLine($"=== 确保缩放一致性 ===");
                        System.Diagnostics.Debug.WriteLine($"当前控件ID: {this.ControlId}");
                        System.Diagnostics.Debug.WriteLine($"调用ZoomExtents()确保缩放一致");

                        // 调用ZoomExtents()来确保视图显示所有内容，保持一致的缩放比
                        this.ZoomExtents();

                        System.Diagnostics.Debug.WriteLine($"=== 缩放一致性确保完成 ===");
                    }
                };
                timer.Start();
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine($"确保缩放一致性失败: {ex.Message}");
            }
        }

        /// <summary>
        /// 重置边界值
        /// </summary>
        private void ResetBoundaries()
        {
            _minX = double.MaxValue;
            _minY = double.MaxValue;
            _maxX = double.MinValue;
            _maxY = double.MinValue;
        }

        /// <summary>
        /// 更新实体的边界范围
        /// </summary>
        private void UpdateBoundaries(EntityObject entity)
        {
            switch (entity)
            {
                case Line line:
                    _minX = Math.Min(_minX, Math.Min(line.StartPoint.X, line.EndPoint.X));
                    _minY = Math.Min(_minY, Math.Min(line.StartPoint.Y, line.EndPoint.Y));
                    _maxX = Math.Max(_maxX, Math.Max(line.StartPoint.X, line.EndPoint.X));
                    _maxY = Math.Max(_maxY, Math.Max(line.StartPoint.Y, line.EndPoint.Y));
                    break;

                case Circle circle:
                    foreach (var point in GetCirclePoints(circle))
                    {
                        _minX = Math.Min(_minX, point.X);
                        _minY = Math.Min(_minY, point.Y);
                        _maxX = Math.Max(_maxX, point.X);
                        _maxY = Math.Max(_maxY, point.Y);
                    }
                    break;

                case Arc arc:
                    foreach (var point in GetArcPoints(arc))
                    {
                        _minX = Math.Min(_minX, point.X);
                        _minY = Math.Min(_minY, point.Y);
                        _maxX = Math.Max(_maxX, point.X);
                        _maxY = Math.Max(_maxY, point.Y);
                    }
                    break;

                case Text text:
                    _minX = Math.Min(_minX, text.Position.X);
                    _minY = Math.Min(_minY, text.Position.Y);
                    _maxX = Math.Max(_maxX, text.Position.X);
                    _maxY = Math.Max(_maxY, text.Position.Y);
                    break;

                case MText mText:
                    _minX = Math.Min(_minX, mText.Position.X);
                    _minY = Math.Min(_minY, mText.Position.Y);
                    _maxX = Math.Max(_maxX, mText.Position.X);
                    _maxY = Math.Max(_maxY, mText.Position.Y);
                    break;

                case Ellipse ellipse:
                    foreach (var point in GetEllipsePoints(ellipse))
                    {
                        _minX = Math.Min(_minX, point.X);
                        _minY = Math.Min(_minY, point.Y);
                        _maxX = Math.Max(_maxX, point.X);
                        _maxY = Math.Max(_maxY, point.Y);
                    }
                    break;
            }
        }

        /// <summary>
        /// 根据边界范围调整相机视角
        /// </summary>
        private void AdjustCameraView()
        {
            try
            {
                System.Diagnostics.Debug.WriteLine($"=== 开始调整相机视图 ===");
                System.Diagnostics.Debug.WriteLine($"当前边界: X[{_minX:F2}, {_maxX:F2}], Y[{_minY:F2}, {_maxY:F2}]");

                // 如果边界值没有变化，说明没有实体，使用默认值
                if (_minX == double.MaxValue || _maxX == double.MinValue || _minY == double.MaxValue || _maxY == double.MinValue)
                {
                    _minX = 0;
                    _minY = 0;
                    _maxX = 1000;
                    _maxY = 1000;
                    System.Diagnostics.Debug.WriteLine($"使用默认边界值: X[{_minX:F2}, {_maxX:F2}], Y[{_minY:F2}, {_maxY:F2}]");
                }

                // 确保边界值有效
                if (_minX >= _maxX || _minY >= _maxY)
                {
                    _minX = 0;
                    _minY = 0;
                    _maxX = 1000;
                    _maxY = 1000;
                    System.Diagnostics.Debug.WriteLine($"边界值无效，重置为默认值: X[{_minX:F2}, {_maxX:F2}], Y[{_minY:F2}, {_maxY:F2}]");
                }

                // 计算中心点和范围
                var centerX = (_minX + _maxX) / 2;
                var centerY = (_minY + _maxY) / 2;
                var size = Math.Max(_maxX - _minX, _maxY - _minY);

                // 确保最小尺寸
                size = Math.Max(size, 100);

                System.Diagnostics.Debug.WriteLine($"计算的中心点: ({centerX:F2}, {centerY:F2})");
                System.Diagnostics.Debug.WriteLine($"计算的尺寸: {size:F2}");

                // 调整摄像机位置和视角
                var cameraZ = size * 2;
                Camera.Position = new Point3D(centerX, centerY, cameraZ);
                Camera.LookDirection = new Vector3D(0, 0, -1);
                Camera.UpDirection = new Vector3D(0, 1, 0);
                Camera.NearPlaneDistance = 0.1;

                System.Diagnostics.Debug.WriteLine($"相机位置设置为: ({Camera.Position.X:F2}, {Camera.Position.Y:F2}, {Camera.Position.Z:F2})");

                // 自动调整视角
                //ZoomExtents();

                System.Diagnostics.Debug.WriteLine($"=== 相机视图调整完成 ===");
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine($"调整相机视图失败: {ex.Message}");
                System.Diagnostics.Debug.WriteLine($"异常堆栈: {ex.StackTrace}");
            }
        }

        private void AnnotationDisplayerControl_Loaded(object sender, System.Windows.RoutedEventArgs e)
        {
            Children.Clear(); // 清空视图 

            Background = new SolidColorBrush(Color.FromRgb(33, 40, 48));

            Children.Add(new SunLight());

            // 重置边界值
            ResetBoundaries();

            // 初始化镜像变换管理器（此时ControlId应该已经设置）
            InitializeMirrorTransformManager();

            BuildLayerNameToColorMap();

        }




        /// <summary>
        /// 当前以中下为基本
        /// </summary>
        /// <param name="attachmentPoint"></param>
        /// <param name="basePoint"></param>
        /// <param name="width"></param>
        /// <param name="height"></param>
        /// <returns></returns>
        private Point3D AdjustBasePointForAlignment(
            MTextAttachmentPoint attachmentPoint,
            Point3D basePoint,
            double width,
            double height)
        {
            double offsetX = 0;
            double offsetY = 0;

            // 根据对齐方式调整水平偏移
            switch (attachmentPoint)
            {
                case MTextAttachmentPoint.TopLeft:
                case MTextAttachmentPoint.MiddleLeft:
                case MTextAttachmentPoint.BottomLeft:
                    offsetX = -width / 6; // 左对齐
                    break;
                case MTextAttachmentPoint.TopCenter:
                case MTextAttachmentPoint.MiddleCenter:
                case MTextAttachmentPoint.BottomCenter:
                    offsetX = -width * 1.4;  // 中对齐
                    break;

                case MTextAttachmentPoint.TopRight:
                case MTextAttachmentPoint.MiddleRight:
                case MTextAttachmentPoint.BottomRight:
                    offsetX = -width * 5 / 6; // 右对齐
                    break;
            }

            // 根据对齐方式调整垂直偏移
            switch (attachmentPoint)
            {
                case MTextAttachmentPoint.TopLeft:
                case MTextAttachmentPoint.TopCenter:
                case MTextAttachmentPoint.TopRight:
                    offsetY = height / 6; // 上对齐
                    break;
                case MTextAttachmentPoint.MiddleLeft:
                case MTextAttachmentPoint.MiddleCenter:
                case MTextAttachmentPoint.MiddleRight:
                    offsetY = height / 2; // 中对齐
                    break;

                case MTextAttachmentPoint.BottomLeft:
                case MTextAttachmentPoint.BottomCenter:
                case MTextAttachmentPoint.BottomRight:
                    offsetY = 0; // 下对齐
                    offsetY = -height / 6;
                    break;
            }

            // 返回调整后的基点
            return new Point3D(basePoint.X + offsetX, basePoint.Y + offsetY, basePoint.Z);
        }


        public static ModelVisual3D GetTextVisual(string text, Brush textColor, bool bDoubleSided, double height, Point3D basePoint,
            Vector3D over, Vector3D up, double rotationAngle, string fontFamily = "Cascadia Code", bool underline = false)
        {
            // 创建 TextBlock 作为文字内容
            TextBlock tb = new TextBlock(new Run(text));
            tb.Foreground = textColor;
            tb.FontFamily = new FontFamily(fontFamily); // 设置字体
            tb.FontWeight = FontWeights.Normal;
            tb.FontStretch = FontStretches.Condensed;

            // 添加下划线
            if (underline)
            {
                tb.TextDecorations = TextDecorations.Underline;
            }

            // 使用 TextBlock 创建材质
            DiffuseMaterial mat = new DiffuseMaterial();
            mat.Brush = new VisualBrush(tb);

            // 计算文字宽度（假设字符是正方形）
            double width = text.Length * height * 0.85f;

            // 调整基准点为左下角
            Point3D p0 = basePoint - up * height / 6; // 左下角
            Point3D p1 = p0 + up * height; // 左上角
            Point3D p2 = p0 + over * width; // 右下角
            Point3D p3 = p0 + up * height + over * width; // 右上角

            // 应用旋转变换
            Transform3DGroup transformGroup = new Transform3DGroup();
            transformGroup.Children.Add(new RotateTransform3D(
                new AxisAngleRotation3D(new Vector3D(0, 0, 1), rotationAngle), basePoint));

            p0 = transformGroup.Transform(p0);
            p1 = transformGroup.Transform(p1);
            p2 = transformGroup.Transform(p2);
            p3 = transformGroup.Transform(p3);

            // 创建 MeshGeometry3D
            MeshGeometry3D mg = new MeshGeometry3D();
            mg.Positions = new Point3DCollection { p0, p1, p2, p3 };

            if (bDoubleSided)
            {
                mg.Positions.Add(p0); // 4
                mg.Positions.Add(p1); // 5
                mg.Positions.Add(p2); // 6
                mg.Positions.Add(p3); // 7
            }

            // 定义三角形索引
            mg.TriangleIndices.Add(0);
            mg.TriangleIndices.Add(3);
            mg.TriangleIndices.Add(1);
            mg.TriangleIndices.Add(0);
            mg.TriangleIndices.Add(2);
            mg.TriangleIndices.Add(3);

            if (bDoubleSided)
            {
                mg.TriangleIndices.Add(4);
                mg.TriangleIndices.Add(5);
                mg.TriangleIndices.Add(7);
                mg.TriangleIndices.Add(4);
                mg.TriangleIndices.Add(7);
                mg.TriangleIndices.Add(6);
            }

            // 定义纹理坐标
            mg.TextureCoordinates.Add(new System.Windows.Point(0, 1));
            mg.TextureCoordinates.Add(new System.Windows.Point(0, 0));
            mg.TextureCoordinates.Add(new System.Windows.Point(1, 1));
            mg.TextureCoordinates.Add(new System.Windows.Point(1, 0));

            if (bDoubleSided)
            {
                mg.TextureCoordinates.Add(new System.Windows.Point(0, 1));
                mg.TextureCoordinates.Add(new System.Windows.Point(0, 0));
                mg.TextureCoordinates.Add(new System.Windows.Point(1, 1));
                mg.TextureCoordinates.Add(new System.Windows.Point(1, 0));
            }

            // 创建 ModelVisual3D
            ModelVisual3D mv3d = new ModelVisual3D
            {
                Content = new GeometryModel3D(mg, mat)
            };

            return mv3d;
        }



        /// <summary>
        /// 创建镜像文字视觉对象（实现真正的文字镜像效果）
        /// </summary>
        public static ModelVisual3D GetMirrorTextVisual(string text, Brush textColor, bool bDoubleSided, double height, Point3D basePoint,
            Vector3D over, Vector3D up, double rotationAngle, string fontFamily = "Cascadia Code", bool underline = false)
        {
            try
            {
                //System.Diagnostics.Debug.WriteLine($"=== 开始创建镜像文字视觉对象 ===");
                //System.Diagnostics.Debug.WriteLine($"原始文字: '{text}'");
                //System.Diagnostics.Debug.WriteLine($"基准点: ({basePoint.X:F2}, {basePoint.Y:F2}, {basePoint.Z:F2})");
                // 创建普通的TextBlock，使用镜像文字
                TextBlock tb = new TextBlock(new Run(text));
                tb.Foreground = textColor;
                tb.FontFamily = new FontFamily(fontFamily);
                tb.FontWeight = FontWeights.Normal;
                tb.FontStretch = FontStretches.Condensed;

                if (underline)
                {
                    tb.TextDecorations = TextDecorations.Underline;
                }

                // 创建材质
                DiffuseMaterial mat = new DiffuseMaterial();
                mat.Brush = new VisualBrush(tb);

                // 计算文字宽度
                double width = text.Length * height * 0.85f;

                // 调整基准点为左下角 - up * height / 6
                Point3D p0 = basePoint;
                Point3D p1 = p0 + up * height;
                Point3D p2 = p0 + over * width;
                Point3D p3 = p0 + up * height + over * width;

                // 应用旋转变换
                Transform3DGroup transformGroup = new Transform3DGroup();
                transformGroup.Children.Add(new RotateTransform3D(
                    new AxisAngleRotation3D(new Vector3D(0, 0, 1), rotationAngle), basePoint));

                p0 = transformGroup.Transform(p0);
                p1 = transformGroup.Transform(p1);
                p2 = transformGroup.Transform(p2);
                p3 = transformGroup.Transform(p3);

                // 创建 MeshGeometry3D
                MeshGeometry3D mg = new MeshGeometry3D();
                mg.Positions = new Point3DCollection { p0, p1, p2, p3 };

                if (bDoubleSided)
                {
                    mg.Positions.Add(p0);
                    mg.Positions.Add(p1);
                    mg.Positions.Add(p2);
                    mg.Positions.Add(p3);
                }

                // 定义三角形索引
                mg.TriangleIndices.Add(0);
                mg.TriangleIndices.Add(3);
                mg.TriangleIndices.Add(1);
                mg.TriangleIndices.Add(0);
                mg.TriangleIndices.Add(2);
                mg.TriangleIndices.Add(3);

                if (bDoubleSided)
                {
                    mg.TriangleIndices.Add(4);
                    mg.TriangleIndices.Add(5);
                    mg.TriangleIndices.Add(7);
                    mg.TriangleIndices.Add(4);
                    mg.TriangleIndices.Add(7);
                    mg.TriangleIndices.Add(6);
                }

                // 使用标准纹理坐标（不需要翻转，因为文字本身已经是镜像的）
                mg.TextureCoordinates.Add(new System.Windows.Point(0, 1));
                mg.TextureCoordinates.Add(new System.Windows.Point(0, 0));
                mg.TextureCoordinates.Add(new System.Windows.Point(1, 1));
                mg.TextureCoordinates.Add(new System.Windows.Point(1, 0));

                if (bDoubleSided)
                {
                    //mg.TextureCoordinates.Add(new System.Windows.Point(0, 1));
                    //mg.TextureCoordinates.Add(new System.Windows.Point(0, 0));
                    //mg.TextureCoordinates.Add(new System.Windows.Point(1, 1));
                    //mg.TextureCoordinates.Add(new System.Windows.Point(1, 0));

                    mg.TextureCoordinates.Add(new System.Windows.Point(1, 1));
                    mg.TextureCoordinates.Add(new System.Windows.Point(1, 0));
                    mg.TextureCoordinates.Add(new System.Windows.Point(0, 1));
                    mg.TextureCoordinates.Add(new System.Windows.Point(0, 0));
                }

                // 创建基础几何模型
                GeometryModel3D geometryModel = new GeometryModel3D(mg, mat);

                // 创建 ModelVisual3D
                ModelVisual3D mv3d = new ModelVisual3D
                {
                    Content = geometryModel
                };

                //System.Diagnostics.Debug.WriteLine($"镜像文字视觉对象创建成功（使用智能字符镜像）");
                return mv3d;
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine($"创建镜像文字视觉对象失败: {ex.Message}");
                return GetTextVisual(text, textColor, bDoubleSided, height, basePoint, over, up, rotationAngle, fontFamily, underline);
            }
        }

        public static ModelVisual3D GetMTextVisual(string text, Brush textColor, bool bDoubleSided, double height,
            Point3D basePoint, Vector3D over, Vector3D up, double rotationAngle, Vector3D offset, string fontFamily, bool underline = false)
        {
            // 创建 TextBlock 作为文字内容
            TextBlock tb = new TextBlock(new Run(text));
            tb.Foreground = textColor;
            tb.FontFamily = new FontFamily(fontFamily); // 设置字体
            tb.FontWeight = FontWeights.Thin;
            tb.FontStretch = FontStretches.Condensed;

            // 添加下划线
            if (underline)
            {
                tb.TextDecorations = TextDecorations.Underline;
            }

            // 使用 TextBlock 创建材质
            DiffuseMaterial mat = new DiffuseMaterial();
            mat.Brush = new VisualBrush(tb);

            // 计算文字宽度（假设字符是正方形）
            double width = text.Length * height * 0.9f;

            // 调整基准点为左下角
            Point3D p0 = basePoint; // 左下角 - up * height / 6
            Point3D p1 = p0 + up * height; // 左上角
            Point3D p2 = p0 + over * width; // 右下角
            Point3D p3 = p0 + up * height + over * width; // 右上角

            // 应用旋转变换
            Transform3DGroup transformGroup = new Transform3DGroup();
            transformGroup.Children.Add(new RotateTransform3D(
                new AxisAngleRotation3D(new Vector3D(0, 0, 1), rotationAngle), basePoint));

            p0 += offset;
            p1 += offset;
            p2 += offset;
            p3 += offset;

            p0 = transformGroup.Transform(p0);
            p1 = transformGroup.Transform(p1);
            p2 = transformGroup.Transform(p2);
            p3 = transformGroup.Transform(p3);

            // 创建 MeshGeometry3D
            MeshGeometry3D mg = new MeshGeometry3D();
            mg.Positions = new Point3DCollection { p0, p1, p2, p3 };

            if (bDoubleSided)
            {
                mg.Positions.Add(p0); // 4
                mg.Positions.Add(p1); // 5
                mg.Positions.Add(p2); // 6
                mg.Positions.Add(p3); // 7
            }

            // 定义三角形索引
            mg.TriangleIndices.Add(0);
            mg.TriangleIndices.Add(3);
            mg.TriangleIndices.Add(1);
            mg.TriangleIndices.Add(0);
            mg.TriangleIndices.Add(2);
            mg.TriangleIndices.Add(3);

            if (bDoubleSided)
            {
                mg.TriangleIndices.Add(4);
                mg.TriangleIndices.Add(5);
                mg.TriangleIndices.Add(7);
                mg.TriangleIndices.Add(4);
                mg.TriangleIndices.Add(7);
                mg.TriangleIndices.Add(6);
            }

            // 定义纹理坐标
            mg.TextureCoordinates.Add(new System.Windows.Point(0, 1));
            mg.TextureCoordinates.Add(new System.Windows.Point(0, 0));
            mg.TextureCoordinates.Add(new System.Windows.Point(1, 1));
            mg.TextureCoordinates.Add(new System.Windows.Point(1, 0));

            if (bDoubleSided)
            {
                mg.TextureCoordinates.Add(new System.Windows.Point(0, 1));
                mg.TextureCoordinates.Add(new System.Windows.Point(0, 0));
                mg.TextureCoordinates.Add(new System.Windows.Point(1, 1));
                mg.TextureCoordinates.Add(new System.Windows.Point(1, 0));
            }

            // 创建 ModelVisual3D
            ModelVisual3D mv3d = new ModelVisual3D
            {
                Content = new GeometryModel3D(mg, mat)
            };

            return mv3d;
        }



        private ModelVisual3D GetCircleVisual(netDxf.Entities.Circle circle)
        {
            bool isContinuous;

            var lineType = GetLineDashStyle(circle, out isContinuous);

            // 获取圆的点集合
            var circlePoints = GetCirclePoints(circle);

            if (isContinuous)
            {
                // 使用连续线段绘制圆
                return CreateContinuousLinesVisual(circlePoints, ConvertDxfColor(circle.Color), 1);
            }
            else
            {
                // 使用虚线绘制圆
                return CreateDashedVisual(circlePoints, lineType, ConvertDxfColor(circle.Color), 1);
            }
        }


        private DashStyle GetLineDashStyle(EntityObject entityObj, out bool isContinuous)
        {
            // 获取实体的线型名称
            string lineTypeName = entityObj.Linetype?.Name ?? "Continuous";

            // 如果线型名称为 "ByLayer"，从图层中获取线型名称
            if (lineTypeName.Equals("ByLayer", StringComparison.OrdinalIgnoreCase))
            {
                lineTypeName = entityObj.Layer?.Linetype?.Name ?? "Continuous";
            }

            // 从 LinDashStyleConverter 获取 DashStyle
            DashStyle dashStyle = LinDashStyleConverter.GetDashStyle(lineTypeName);

            // 判断是否为连续线
            isContinuous = dashStyle == DashStyles.Solid;

            return dashStyle;
        }


        private List<Point3D> GetCirclePoints(netDxf.Entities.Circle circle)
        {
            var points = new List<Point3D>();
            int segments = 180; // 分段数，越大越平滑

            // 圆的参数
            var center = circle.Center;
            var radius = circle.Radius;

            // 计算角度步长
            double angleStep = 2 * Math.PI / segments;

            for (int i = 0; i <= segments; i++)
            {
                double angle = i * angleStep;
                double x = center.X + radius * Math.Cos(angle);
                double y = center.Y + radius * Math.Sin(angle);
                points.Add(new Point3D(x, y, center.Z));
            }

            return points;
        }


        private ModelVisual3D GetEllipseVisual(netDxf.Entities.Ellipse ellipse)
        {
            bool isContinuous = false;

            var linDashStyle = GetLineDashStyle(ellipse, out isContinuous);

            if (isContinuous)
            {
                // 使用线段模拟椭圆，而不是3D网格
                var ellipsePoints = GetEllipsePoints(ellipse);
                return CreateContinuousLinesVisual(ellipsePoints, ConvertDxfColor(ellipse.Color), 1);

            }
            else
            {
                // 使用分段线模拟虚线椭圆
                var ellipsePoints = GetEllipsePoints(ellipse);
                return CreateDashedVisual(ellipsePoints, linDashStyle, ConvertDxfColor(ellipse.Color), 1);
            }
        }

        private LinesVisual3D CreateContinuousLinesVisual(List<Point3D> points, Color color, double thickness)
        {
            var continuousPoints = new Point3DCollection();

            // 将相邻点重复添加到集合中，形成连续的线段
            for (int i = 0; i < points.Count - 1; i++)
            {
                continuousPoints.Add(points[i]);     // 起点
                continuousPoints.Add(points[i + 1]); // 终点
            }

            return new LinesVisual3D
            {
                Points = continuousPoints,
                Color = color,
                Thickness = thickness
            };
        }


        private List<Point3D> GetEllipsePoints(netDxf.Entities.Ellipse ellipse)
        {
            var points = new List<Point3D>();
            int segments = 180; // 分段数，越大越平滑

            // 椭圆参数
            var center = ellipse.Center;
            var majorAxis = ellipse.MajorAxis;
            var minorAxis = ellipse.MinorAxis; // 使用 MinorAxis 替代 RadiusRatio
            var rotation = ellipse.Rotation * Math.PI / 180.0; // 旋转角度（弧度）
            var startAngle = ellipse.StartAngle * Math.PI / 180.0; // 起始角度（弧度）
            var endAngle = ellipse.EndAngle * Math.PI / 180.0; // 结束角度（弧度）


            // 判断是否是闭合椭圆
            bool isClosed = Math.Abs(endAngle - startAngle) < 1e-6;
            if (isClosed)
            {
                endAngle = startAngle + 2 * Math.PI; // 闭合椭圆，设置结束角为起始角加360度
            }

            // 计算角度步长
            double angleStep = (endAngle - startAngle) / segments;

            for (int i = 0; i < segments; i++) // 注意这里是 < segments，避免重复点
            {
                double angle = startAngle + i * angleStep;
                double x = majorAxis * Math.Cos(angle);
                double y = minorAxis * Math.Sin(angle);

                // 应用旋转变换
                double rotatedX = x * Math.Cos(rotation) - y * Math.Sin(rotation);
                double rotatedY = x * Math.Sin(rotation) + y * Math.Cos(rotation);

                points.Add(new Point3D(center.X + rotatedX, center.Y + rotatedY, center.Z));
            }

            // 如果是闭合椭圆，确保首尾相连
            if (isClosed && points.Count > 1)
            {
                points.Add(points[0]);
            }

            return points;
        }


        private ModelVisual3D GetArcVisual(Arc arc)
        {
            bool isContinuous = false;

            var linetype = GetLineDashStyle(arc, out isContinuous);

            // 获取弧的点集合
            var arcPoints = GetArcPoints(arc);

            if (isContinuous)
            {
                // 使用连续线段绘制弧
                return CreateContinuousLinesVisual(arcPoints, ConvertDxfColor(arc.Color, arc.Layer), 1);
            }
            else
            {
                // 使用虚线绘制弧
                return CreateDashedVisual(arcPoints, linetype, ConvertDxfColor(arc.Color, arc.Layer), 1);
            }
        }


        private List<Point3D> GetArcPoints(Arc arc)
        {
            var points = new List<Point3D>();
            int segments = 72; // 分段数，越大越平滑

            // 弧的参数
            var startAngle = arc.StartAngle * Math.PI / 180.0; // 起始角度（弧度）
            var endAngle = arc.EndAngle * Math.PI / 180.0;     // 结束角度（弧度）

            // 按顺时针原则调整结束角度
            if (endAngle < startAngle)
            {
                endAngle += 2 * Math.PI; // 将结束角度调整到大于起始角度
            }

            // 计算总角度
            double totalAngle = endAngle - startAngle;

            // 计算角度步长
            double angleStep = totalAngle / segments;

            for (int i = 0; i <= segments; i++)
            {
                double angle = startAngle + i * angleStep;
                double x = arc.Center.X + arc.Radius * Math.Cos(angle);
                double y = arc.Center.Y + arc.Radius * Math.Sin(angle);
                points.Add(new Point3D(x, y, arc.Center.Z));
            }

            return points;
        }


        private LinesVisual3D CreateDashedVisual(List<Point3D> points, DashStyle dashStyle, Color color, double thickness)
        {
            var dashedVisual = new LinesVisual3D
            {
                Thickness = thickness,
                Color = color
            };

            var dashedPoints = new Point3DCollection();

            // 检查 DashStyle 是否有效
            if (dashStyle == null || dashStyle.Dashes == null || dashStyle.Dashes.Count == 0)
            {
                throw new ArgumentException("Invalid DashStyle provided. DashStyle must have at least one dash value.");
            }

            // 遍历点集合，生成虚线段
            for (int i = 0; i < points.Count - 1; i++)
            {
                var start = points[i];
                var end = points[i + 1];
                var segmentVector = end - start;
                var segmentLength = segmentVector.Length;

                double currentLength = 0;
                int dashIndex = 0; // 当前处理的 DashStyle 索引
                bool drawDash = true; // 当前是否绘制虚线段

                while (currentLength < segmentLength)
                {
                    // 获取当前 dash 的长度
                    double dashLength = Math.Abs(dashStyle.Dashes[dashIndex]);
                    double remainingLength = segmentLength - currentLength;

                    // 如果当前 dash 长度超过剩余长度，截断
                    if (dashLength > remainingLength)
                    {
                        dashLength = remainingLength;
                    }

                    if (drawDash)
                    {
                        // 计算虚线段的起点和终点
                        var segmentStart = start + (segmentVector * (currentLength / segmentLength));
                        var segmentEnd = start + (segmentVector * ((currentLength + dashLength) / segmentLength));
                        dashedPoints.Add(segmentStart);
                        dashedPoints.Add(segmentEnd);
                    }

                    // 更新当前长度
                    currentLength += dashLength;

                    // 切换到下一个 dash
                    dashIndex = (dashIndex + 1) % dashStyle.Dashes.Count;
                    drawDash = !drawDash; // 切换绘制状态
                }
            }

            dashedVisual.Points = dashedPoints;
            return dashedVisual;
        }



        // 将 DXF 的颜色转换为 WPF 的颜色
        private Color ConvertDxfColor(netDxf.AciColor dxfColor, netDxf.Tables.Layer layer = null)
        {
            if (dxfColor == null)
            {
                return Colors.Black; // 默认颜色
            }

            if (dxfColor.IsByLayer)
            {

                if (_layerNameToColorMap != null && _layerNameToColorMap.ContainsKey(layer.Name))
                {
                    return _layerNameToColorMap[layer.Name];
                }
                else if (layer != null && layer.Color != null) // 如果是 ByLayer，尝试从图层中获取颜色
                {
                    return MapAciColorIntelligently(layer.Color.Index);
                }
                return Colors.Gray; // 如果图层颜色不可用，返回默认灰色
            }

            if (dxfColor.IsByBlock)
            {
                // 如果是 ByBlock，返回默认颜色（可根据需求扩展）
                return Colors.Gray;
            }

            //如果是 RGB 颜色，直接转换
            if (dxfColor.UseTrueColor)
            {
                return Color.FromRgb(dxfColor.R, dxfColor.G, dxfColor.B);
            }

            // 如果是 ACI 索引颜色，映射到 RGB
            return MapAciColorIntelligently(dxfColor.Index);
        }



        /// <summary>
        /// 智能ACI颜色映射（作为后备方案）
        /// </summary>
        private Color MapAciColorIntelligently(short index)
        {
            // 如果是标准ACI颜色（1-7），直接映射
            if (index >= 1 && index <= 7)
            {
                var standardColors = new Dictionary<short, Color>
                {
                    { 1, Color.FromRgb(255, 0, 0) },      // 红色
                    { 2, Color.FromRgb(255, 255, 0) },    // 黄色
                    { 3, Color.FromRgb(0, 255, 0) },      // 绿色
                    { 4, Color.FromRgb(0, 255, 255) },    // 青色
                    { 5, Color.FromRgb(0, 0, 255) },      // 蓝色
                    { 6, Color.FromRgb(255, 0, 255) },    // 品红
                    { 7, Color.FromRgb(255, 255, 255) }   // 白色
                };
                return standardColors.ContainsKey(index) ? standardColors[index] : Colors.Black;
            }

            // 如果是扩展ACI颜色（8-255），使用智能映射算法
            if (index >= 8 && index <= 255)
            {
                // 将索引映射到HSV色彩空间，然后转换为RGB
                double hue = (index - 8) * 360.0 / 248.0; // 0-360度色相
                double saturation = 0.8; // 80%饱和度
                double value = 0.8; // 80%明度

                // 根据索引范围调整饱和度和明度
                if (index >= 8 && index <= 15) // 基础颜色变体
                {
                    saturation = 0.9;
                    value = 0.9;
                }
                else if (index >= 16 && index <= 31) // 深色变体
                {
                    saturation = 0.7;
                    value = 0.6;
                }
                else if (index >= 32 && index <= 47) // 暗色变体
                {
                    saturation = 0.6;
                    value = 0.4;
                }
                else if (index >= 48 && index <= 63) // 更暗色变体
                {
                    saturation = 0.5;
                    value = 0.3;
                }
                else if (index >= 64 && index <= 79) // 最暗色变体
                {
                    saturation = 0.4;
                    value = 0.2;
                }
                else if (index >= 80 && index <= 95) // 浅色变体
                {
                    saturation = 0.6;
                    value = 0.9;
                }
                else if (index >= 96 && index <= 111) // 更浅色变体
                {
                    saturation = 0.5;
                    value = 0.95;
                }
                else if (index >= 112 && index <= 127) // 最浅色变体
                {
                    saturation = 0.4;
                    value = 0.98;
                }
                else if (index >= 128 && index <= 255) // 灰度色变体
                {
                    // 灰度色：将索引映射到0-255的灰度值
                    int grayValue = (int)((index - 128) * 255.0 / 127.0);
                    grayValue = Math.Max(0, Math.Min(255, grayValue));
                    return Color.FromRgb((byte)grayValue, (byte)grayValue, (byte)grayValue);
                }

                // 将HSV转换为RGB
                return HsvToRgb(hue, saturation, value);
            }

            // 默认返回黑色
            return Colors.Black;
        }


        /// <summary>
        /// 将HSV颜色转换为RGB颜色
        /// </summary>
        private Color HsvToRgb(double h, double s, double v)
        {
            double c = v * s;
            double x = c * (1 - Math.Abs((h / 60) % 2 - 1));
            double m = v - c;

            double r = 0, g = 0, b = 0;

            if (h >= 0 && h < 60)
            {
                r = c; g = x; b = 0;
            }
            else if (h >= 60 && h < 120)
            {
                r = x; g = c; b = 0;
            }
            else if (h >= 120 && h < 180)
            {
                r = 0; g = c; b = x;
            }
            else if (h >= 180 && h < 240)
            {
                r = 0; g = x; b = c;
            }
            else if (h >= 240 && h < 300)
            {
                r = x; g = 0; b = c;
            }
            else if (h >= 300 && h < 360)
            {
                r = c; g = 0; b = x;
            }

            return Color.FromRgb(
                (byte)((r + m) * 255),
                (byte)((g + m) * 255),
                (byte)((b + m) * 255)
            );
        }



        // 1. 文字宽高测量方法 - 与 GetTextVisual 中的字体设置保持一致
        private Size MeasureText(string text, double fontSize, string fontFamily)
        {
            var tb = new System.Windows.Controls.TextBlock(new Run(text))
            {
                FontSize = fontSize,
                FontFamily = new System.Windows.Media.FontFamily(fontFamily),
                FontWeight = FontWeights.Normal,
                FontStretch = FontStretches.Condensed
            };
            tb.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
            return tb.DesiredSize;
        }

        // 移除当前编辑框
        private void RemoveCurrentEditAdorner()
        {
            if (_currentEditAdorner != null)
            {
                var adornerLayer = AdornerLayer.GetAdornerLayer(this);
                if (adornerLayer != null)
                {
                    adornerLayer.Remove(_currentEditAdorner);
                }
                _currentEditAdorner = null;
            }
        }

        /// <summary>
        /// 创建新标注（CAD标准模式：先弹编辑框，确认后创建实体）
        /// </summary>
        /// <param name="mousePosition">鼠标位置</param>
        private void CreateNewAnnotation(Point mousePosition)
        {
            // 移除当前编辑框
            RemoveCurrentEditAdorner();

            // 将鼠标位置转换为3D世界坐标
            var viewportPos = mousePosition;
            var worldPos = Viewport3DHelper.UnProject(this.Viewport, viewportPos, new Point3D(0, 0, 0), new Vector3D(0, 0, 1));

            if (worldPos == null)
            {
                // 如果转换失败，使用默认位置
                worldPos = new Point3D(0, 0, 0);
            }

            // 生成唯一ID
            string pendingTextId = "Pending_" + Guid.NewGuid().ToString();

            // 创建临时文字信息（还未创建视觉对象）
            var pendingTextInfo = new TextInfo
            {
                Id = pendingTextId,
                Text = "", // 开始时为空，等待用户输入
                Position = worldPos.Value,
                Height = 10.0,
                Rotation = 0.0,
                LayerName = "Annotations",
                Color = Colors.Black,
                Underline = false,
                OriginalEntity = null // 标记为新增状态
            };

            // 暂存待创建的文字信息
            _textInfoMap[pendingTextId] = pendingTextInfo;

            // 直接弹出编辑框，不创建视觉对象
            ShowInlineTextBoxForNewAnnotation(pendingTextId, mousePosition, pendingTextInfo);
        }

        /// <summary>
        /// 为新增标注显示编辑框（无需现有视觉对象）
        /// </summary>
        /// <param name="pendingTextId">待创建的文字ID</param>
        /// <param name="mousePosition">鼠标位置</param>
        /// <param name="textInfo">文字信息</param>
        private void ShowInlineTextBoxForNewAnnotation(string pendingTextId, Point mousePosition, TextInfo textInfo)
        {
            if (_currentEditingMode != EditingMode.Adding) return;

            // 移除当前编辑框
            RemoveCurrentEditAdorner();

            // 创建TextBox
            var tb = new System.Windows.Controls.TextBox
            {
                Text = textInfo.Text,
                Tag = pendingTextId,
                FontSize = 14,
                MinWidth = 100,
                MaxWidth = 300,
                Background = new SolidColorBrush(Color.FromArgb(240, 255, 255, 255)),
                BorderBrush = new SolidColorBrush(Colors.Blue),
                BorderThickness = new System.Windows.Thickness(2)
            };

            // 键盘事件处理
            tb.KeyDown += (s, e) =>
            {
                if (e.Key == System.Windows.Input.Key.Enter)
                {
                    e.Handled = true;
                    // 检查是否是预览模式
                    if (_isInPreviewMode && pendingTextId == _previewAnnotationId)
                    {
                        ConfirmPreviewAnnotation(tb.Text);
                    }
                    else
                    {
                        CommitNewAnnotation(tb, pendingTextId);
                    }
                }
                else if (e.Key == System.Windows.Input.Key.Escape)
                {
                    e.Handled = true;
                    // 检查是否是预览模式
                    if (_isInPreviewMode && pendingTextId == _previewAnnotationId)
                    {
                        ClearPreviewAnnotation();
                    }
                    else
                    {
                        CancelNewAnnotation(pendingTextId);
                    }
                }
            };

            // 失去焦点时取消
            tb.LostFocus += (s, e) =>
            {
                // 检查是否是预览模式
                if (_isInPreviewMode && pendingTextId == _previewAnnotationId)
                {
                    ClearPreviewAnnotation();
                }
                else
                {
                    CancelNewAnnotation(pendingTextId);
                }
            };

            // 计算编辑框位置
            double editBoxX = mousePosition.X + 10;
            double editBoxY = mousePosition.Y - 15;

            // 获取AdornerLayer
            var adornerLayer = AdornerLayer.GetAdornerLayer(this);
            if (adornerLayer != null)
            {
                _currentEditAdorner = new TextEditBoxAdorner(this, tb, new Rect(editBoxX, editBoxY, 120, 25));
                adornerLayer.Add(_currentEditAdorner);

                tb.Focus();
                tb.SelectAll();
            }
        }

        // 2. 显示就地TextBox进行编辑
        public void ShowInlineTextBoxForEdit(ModelVisual3D textVisual, Point? mousePosition = null)
        {
            // 检查是否在编辑模式或新增模式下
            if (_currentEditingMode != EditingMode.Editing && _currentEditingMode != EditingMode.Adding)
            {
                return; // 不在编辑模式或新增模式下，不允许编辑
            }

            // 如果已经有编辑框在显示，先移除它
            RemoveCurrentEditAdorner();

            var tag = textVisual.GetValue(System.Windows.FrameworkElement.TagProperty) as string;
            if (string.IsNullOrEmpty(tag) || !_textInfoMap.ContainsKey(tag)) return;
            var info = _textInfoMap[tag];


            // 计算3D文字四角
            double width3D = info.Text.Length * info.Height * 0.85;
            double height3D = info.Height;
            double angle = info.Rotation * Math.PI / 180.0;
            Vector3D over = new Vector3D(Math.Cos(angle), Math.Sin(angle), 0);
            Vector3D up = new Vector3D(-Math.Sin(angle), Math.Cos(angle), 0);

            Point3D p0 = info.Position - up * height3D / 6; // 左下
            Point3D p1 = p0 + up * height3D; // 左上
            Point3D p2 = p0 + over * width3D; // 右下
            Point3D p3 = p2 + up * height3D; // 右上

            // 投影到屏幕
            var s0 = Point3DToScreen(p0);
            var s1 = Point3DToScreen(p1);
            var s2 = Point3DToScreen(p2);
            var s3 = Point3DToScreen(p3);

            // 计算文字中心点
            double centerX = (s0.X + s1.X + s2.X + s3.X) / 4;
            double centerY = (s0.Y + s1.Y + s2.Y + s3.Y) / 4;

            // 计算文字边界
            double minX = Math.Min(Math.Min(s0.X, s1.X), Math.Min(s2.X, s3.X));
            double minY = Math.Min(Math.Min(s0.Y, s1.Y), Math.Min(s2.Y, s3.Y));
            double maxX = Math.Max(Math.Max(s0.X, s1.X), Math.Max(s2.X, s3.X));
            double maxY = Math.Max(Math.Max(s0.Y, s1.Y), Math.Max(s2.Y, s3.Y));
            double textWidth = maxX - minX;
            double textHeight = maxY - minY;

            // 创建编辑框，初始大小基于文字大小
            double initialBoxWidth = Math.Max(60, textWidth + 20); // 最小宽度60，比文字宽20像素
            double initialBoxHeight = Math.Max(24, textHeight + 8); // 最小高度24，比文字高8像素

            var tb = new System.Windows.Controls.TextBox
            {
                Text = info.Text,
                Width = initialBoxWidth,
                Height = initialBoxHeight,
                FontSize = Math.Max(12, initialBoxHeight * 0.6), // 字体大小基于框高度
                FontFamily = new System.Windows.Media.FontFamily("Cascadia Code"),
                Background = System.Windows.Media.Brushes.White,
                BorderThickness = new System.Windows.Thickness(2),
                BorderBrush = System.Windows.Media.Brushes.DarkBlue,
                Padding = new System.Windows.Thickness(4, 2, 4, 2),
                VerticalContentAlignment = System.Windows.VerticalAlignment.Center,
                HorizontalContentAlignment = System.Windows.HorizontalAlignment.Left,
                // 添加阴影效果
                Effect = new System.Windows.Media.Effects.DropShadowEffect
                {
                    Color = System.Windows.Media.Colors.Black,
                    Direction = 315,
                    ShadowDepth = 3,
                    Opacity = 0.3,
                    BlurRadius = 5
                }
            };

            // 事件处理
            tb.LostFocus += (s, e) =>
            {
                // 失去焦点时，如果是预览模式，应该取消预览（除非内容为空且是默认提示）
                if (_isInPreviewMode && tag == _previewAnnotationId)
                {
                    // 如果内容为空或者是默认提示文字，取消预览
                    if (string.IsNullOrWhiteSpace(tb.Text) || tb.Text == "输入标注内容")
                    {
                        ClearPreviewAnnotation();
                    }
                    else
                    {
                        // 如果有实际内容，也取消预览（只有按Enter才确认）
                        ClearPreviewAnnotation();
                    }
                }
                else
                {
                    // 非预览模式，正常处理
                    CommitInlineEdit(tb, tag);
                }
            };
            tb.KeyDown += (s, e) =>
            {
                if (e.Key == System.Windows.Input.Key.Enter)
                {
                    CommitInlineEdit(tb, tag);
                }
                else if (e.Key == System.Windows.Input.Key.Escape)
                {
                    // ESC键取消编辑
                    if (_isInPreviewMode && tag == _previewAnnotationId)
                    {
                        // 如果是预览模式，清除预览标注
                        ClearPreviewAnnotation();
                    }
                    else
                    {
                        // 普通编辑模式，只移除编辑框
                        RemoveCurrentEditAdorner();
                    }
                }
            };

            tb.TextChanged += (s, e) =>
            {
                // 动态调整宽高
                var newSize = MeasureText(tb.Text, tb.FontSize, tb.FontFamily.Source);
                tb.Width = Math.Max(60, newSize.Width + 16); // 最小宽度60，左右各留8像素
                tb.Height = Math.Max(24, newSize.Height + 8); // 最小高度24，上下各留4像素
            };

            // 计算编辑框的最佳位置 - 避免挡住下面的编辑框
            double editBoxX, editBoxY;

            // 获取屏幕尺寸
            var screenWidth = this.ActualWidth;
            var screenHeight = this.ActualHeight;

            // 计算文字中心点
            double textCenterX = (minX + maxX) / 2;
            double textCenterY = (minY + maxY) / 2;

            // 优先使用鼠标位置，但确保不挡住文字
            if (mousePosition.HasValue)
            {
                editBoxX = mousePosition.Value.X - initialBoxWidth / 2;
                editBoxY = mousePosition.Value.Y - initialBoxHeight / 2;

                // 如果编辑框会挡住文字，调整位置
                if (editBoxX < maxX + 10 && editBoxX + initialBoxWidth > minX - 10 &&
                    editBoxY < maxY + 10 && editBoxY + initialBoxHeight > minY - 10)
                {
                    // 尝试将编辑框放在文字上方
                    editBoxY = minY - initialBoxHeight - 10;
                    if (editBoxY < 5) // 如果上方空间不够，放在下方
                    {
                        editBoxY = maxY + 10;
                    }
                }
            }
            else
            {
                // 默认将编辑框放在文字上方
                editBoxX = textCenterX - initialBoxWidth / 2;
                editBoxY = minY - initialBoxHeight - 10;

                // 如果上方空间不够，放在下方
                if (editBoxY < 5)
                {
                    editBoxY = maxY + 10;
                }
            }



            // 使用AdornerLayer来显示编辑框，确保正确的坐标系统
            var adornerLayer = AdornerLayer.GetAdornerLayer(this);
            if (adornerLayer == null)
            {
                // 如果找不到AdornerLayer，尝试使用父容器
                var parent = this.Parent as System.Windows.Controls.Panel;
                if (parent == null) return;

                // 创建Canvas作为overlay
                System.Windows.Controls.Canvas overlay = null;
                foreach (var child in parent.Children)
                {
                    if (child is System.Windows.Controls.Canvas c && c.Name == "overlayCanvas")
                    {
                        overlay = c;
                        break;
                    }
                }

                if (overlay == null)
                {
                    overlay = new System.Windows.Controls.Canvas { Name = "overlayCanvas" };
                    parent.Children.Add(overlay);
                }

                overlay.Children.Add(tb);

                // 确保编辑框不会超出屏幕边界
                editBoxX = Math.Max(5, Math.Min(editBoxX, overlay.ActualWidth - initialBoxWidth - 5));
                editBoxY = Math.Max(5, Math.Min(editBoxY, overlay.ActualHeight - initialBoxHeight - 5));

                System.Windows.Controls.Canvas.SetLeft(tb, editBoxX);
                System.Windows.Controls.Canvas.SetTop(tb, editBoxY);
            }
            else
            {
                // 使用AdornerLayer，创建一个简单的Adorner来显示编辑框
                _currentEditAdorner = new TextEditBoxAdorner(this, tb, new Rect(editBoxX, editBoxY, initialBoxWidth, initialBoxHeight));
                adornerLayer.Add(_currentEditAdorner);

                // 设置焦点并选中所有文本
                tb.Focus();
                tb.SelectAll();
                return; // 使用Adorner时不需要手动设置位置
            }
            System.Windows.Controls.Panel.SetZIndex(tb, 1000); // 保证在最上层

            tb.Focus();
            tb.SelectAll();
        }

        /// <summary>
        /// 确认新增标注
        /// </summary>
        /// <param name="tb">编辑框</param>
        /// <param name="pendingTextId">待创建的文字ID</param>
        private void CommitNewAnnotation(System.Windows.Controls.TextBox tb, string pendingTextId)
        {
            // 移除编辑框
            RemoveCurrentEditAdorner();

            if (string.IsNullOrWhiteSpace(tb.Text))
            {
                // 如果没有输入内容，取消创建
                CancelNewAnnotation(pendingTextId);
                return;
            }

            if (!_textInfoMap.ContainsKey(pendingTextId))
                return;

            var textInfo = _textInfoMap[pendingTextId];
            textInfo.Text = tb.Text.Trim();

            // 现在创建真正的视觉对象和DXF实体
            //CreateActualAnnotation(pendingTextId, textInfo);
        }

        /// <summary>
        /// 取消新增标注
        /// </summary>
        /// <param name="pendingTextId">待创建的文字ID</param>
        private void CancelNewAnnotation(string pendingTextId)
        {
            // 移除编辑框
            RemoveCurrentEditAdorner();

            // 如果是预览模式，清除预览标注
            if (_isInPreviewMode && pendingTextId == _previewAnnotationId)
            {
                ClearPreviewAnnotation();
            }
            else
            {
                // 从临时映射中移除
                if (_textInfoMap.ContainsKey(pendingTextId))
                {
                    _textInfoMap.Remove(pendingTextId);
                }
            }
        }


        private void CommitInlineEdit(System.Windows.Controls.TextBox tb, string tag)
        {
            // 移除当前编辑框
            RemoveCurrentEditAdorner();

            if (!string.IsNullOrEmpty(tag) && _textInfoMap.ContainsKey(tag))
            {
                // 检查是否是预览模式
                if (_isInPreviewMode && tag == _previewAnnotationId)
                {
                    // 只有按Enter键才会调用这个方法，所以确认预览标注
                    // 但需要检查内容是否有效
                    if (!string.IsNullOrWhiteSpace(tb.Text) && tb.Text != "输入标注内容")
                    {
                        ConfirmPreviewAnnotation(tb.Text);
                    }
                    else
                    {
                        // 内容无效，取消预览
                        ClearPreviewAnnotation();
                    }
                }
                else
                {
                    // 更新现有标注
                    UpdateSelectedText(tb.Text);

                    // 如果是新增的标注（没有OriginalEntity），创建DXF实体
                    // 注意：新增标注现在通过预览模式处理，这个分支保留用于兼容性
                    var textInfo = _textInfoMap[tag];
                    if (textInfo.OriginalEntity == null)
                    {
                        // SaveNewAnnotationToDxf(textInfo); // 已被预览模式替代
                    }
                }
            }
        }

        // 3. 鼠标双击事件触发就地编辑
        private void helixView_MouseDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            // 设置当前控件为活跃视口（节流控制）
            this.SetAsActiveControl();

            // 防止快速重复点击
            var now = DateTime.Now;
            if ((now - _lastClickTime).TotalMilliseconds < CLICK_THRESHOLD_MS)
            {
                return;
            }
            _lastClickTime = now;

            var pos = e.GetPosition(this.Viewport);
            var hits = HelixToolkit.Wpf.Viewport3DHelper.FindHits(this.Viewport, pos);

            if (e.ClickCount == 2)
            {
                // 双击：只在编辑模式下弹出编辑框
                if (_currentEditingMode == EditingMode.Editing)
                {
                    var mousePos = e.GetPosition(this);
                    foreach (var hit in hits)
                    {
                        if (hit.Visual is ModelVisual3D mv3d && IsTextVisual(mv3d))
                        {
                            ShowInlineTextBoxForEdit(mv3d, mousePos);
                            e.Handled = true;
                            return;
                        }
                    }
                }
                return;
            }

            if (e.ClickCount == 1)
            {
                // 单击：直接处理
                HandleSingleClick(e);
            }
        }

        // 新增：真正处理单击选中/拖动/高亮逻辑
        private void HandleSingleClick(MouseButtonEventArgs e)
        {
            // 如果当前有编辑框在显示，在新增模式下允许点击空白区域创建新标注，其他情况阻止操作
            if (_currentEditAdorner != null)
            {
                if (_currentEditingMode == EditingMode.Adding)
                {
                    // 在新增模式下，检查是否点击空白区域
                    var addModePos = e.GetPosition(this.Viewport);
                    var addModeHits = HelixToolkit.Wpf.Viewport3DHelper.FindHits(this.Viewport, addModePos);

                    bool clickedOnText = false;
                    foreach (var hit in addModeHits)
                    {
                        if (hit.Visual is ModelVisual3D mv3d && IsTextVisual(mv3d))
                        {
                            clickedOnText = true;
                            break;
                        }
                    }

                    if (!clickedOnText)
                    {
                        // 点击空白区域，先提交当前编辑，然后创建新标注
                        RemoveCurrentEditAdorner();
                        CreateNewAnnotation(e.GetPosition(this));
                        e.Handled = true;
                        return;
                    }
                }

                // 其他情况阻止操作
                e.Handled = true;
                return;
            }

            // 新增标注模式：点击空白区域创建预览标注
            if (_currentEditingMode == EditingMode.Adding)
            {
                var addModePos = e.GetPosition(this.Viewport);
                var addModeHits = HelixToolkit.Wpf.Viewport3DHelper.FindHits(this.Viewport, addModePos);

                // 如果点击的是空白区域，创建预览标注
                bool clickedOnText = false;
                foreach (var hit in addModeHits)
                {
                    if (hit.Visual is ModelVisual3D mv3d && IsTextVisual(mv3d))
                    {
                        clickedOnText = true;
                        break;
                    }
                }

                if (!clickedOnText)
                {
                    // 如果已经有预览标注且正在编辑，忽略这次点击
                    if (_isInPreviewMode && _currentEditAdorner != null)
                    {
                        e.Handled = true;
                        return;
                    }

                    // 如果已经有预览标注，先清除它
                    if (_isInPreviewMode)
                    {
                        ClearPreviewAnnotation();
                    }

                    // 点击空白区域，创建预览标注
                    CreatePreviewAnnotation(e.GetPosition(this));
                    e.Handled = true;
                    return;
                }
                else
                {
                    // 点击现有文字，选中它
                    foreach (var hit in addModeHits)
                    {
                        if (hit.Visual is ModelVisual3D mv3d && IsTextVisual(mv3d))
                        {
                            HandleTextSelection(mv3d);
                            e.Handled = true;
                            return;
                        }
                    }
                }
            }

            // 删除模式：点击文字标注弹出确认删除对话框
            if (_currentEditingMode == EditingMode.Deleting)
            {
                var deleteModeHits = HelixToolkit.Wpf.Viewport3DHelper.FindHits(this.Viewport, e.GetPosition(this.Viewport));
                foreach (var hit in deleteModeHits)
                {
                    if (hit.Visual is ModelVisual3D mv3d && IsTextVisual(mv3d))
                    {
                        // 选中文字并弹出确认删除对话框
                        HandleTextSelection(mv3d);
                        ShowDeleteConfirmationDialog(mv3d, e.GetPosition(this));
                        e.Handled = true;
                        return;
                    }
                }
                // 点击空白区域清除选中
                ClearTextSelection();
                e.Handled = true;
                return;
            }

            // 如果不在编辑模式下，只允许基本的选中操作，不允许编辑
            if (_currentEditingMode != EditingMode.Editing && _currentEditingMode != EditingMode.Adding)
            {
                // 在非编辑模式下，只处理基本的文字选中，不显示编辑手柄
                var nonEditHits = HelixToolkit.Wpf.Viewport3DHelper.FindHits(this.Viewport, e.GetPosition(this.Viewport));
                foreach (var hit in nonEditHits)
                {
                    if (hit.Visual is ModelVisual3D mv3d && IsTextVisual(mv3d))
                    {
                        HandleTextSelection(mv3d);
                        e.Handled = true;
                        return;
                    }
                }
                // 点击空白区域清除选中
                ClearTextSelection();
                e.Handled = true;
                return;
            }

            // Reset state at the beginning of a new potential gesture
            _mouseDownPos = e.GetPosition(this);
            _isDragGesture = false;
            _isDraggingText = false;
            _isRotating = false;
            _isResizing = false;

            var pos = _mouseDownPos.Value;

            // 只在编辑模式下处理编辑手柄交互
            if (_currentEditingMode == EditingMode.Editing && _textEditAdorner != null)
            {
                // Phase 1: Check for interaction with existing 2D handles of the selected object

                // Check rotation handle
                if (GetRotateHandleRect().Contains(pos))
                {
                    if (_selectedTextInfo != null)
                    {
                        _isRotating = true;
                        // 使用文字左下角作为旋转中心
                        var textBottomLeft = _selectedTextInfo.Position;
                        _rotateCenter2D = Point3DToScreen(textBottomLeft);
                        _rotateStartAngle = Math.Atan2(pos.Y - _rotateCenter2D.Y, pos.X - _rotateCenter2D.X);
                        _rotateOriginAngle = _selectedTextInfo.Rotation;

                        e.Handled = true;
                        return;
                    }
                }

                // Check resize handles
                var handleRects = GetHandleRects();
                for (int i = 0; i < handleRects.Length; i++)
                {
                    if (handleRects[i].Contains(pos))
                    {
                        if (_selectedTextInfo != null)
                        {
                            _isResizing = true;
                            _resizeHandleIndex = i;
                            _dragStartMousePos = pos;
                            _dragStartHeight = _selectedTextInfo.Height;

                            int oppositeIndex = (i + 4) % 8;
                            var oppositeRect = handleRects[oppositeIndex];
                            _dragStartOppositeHandleCenter = new Point(oppositeRect.X + oppositeRect.Width / 2, oppositeRect.Y + oppositeRect.Height / 2);

                            e.Handled = true;
                            return;
                        }
                    }
                }

                // Check for drag-move by clicking inside the adorner bounds
                if (IsPointInRotatedRect(pos, _textEditAdorner.EditRect, _textEditAdorner.RotationAngle))
                {
                    if (_selectedTextInfo != null)
                    {
                        _isDraggingText = true;
                        _dragStartMousePos = e.GetPosition(this.Viewport);
                        _dragStartTextPos = _selectedTextInfo.Position;
                        e.Handled = true;
                        return;
                    }
                }
            }

            // Phase 2: If no handle was hit, check for selection of a new 3D text object
            var hits = HelixToolkit.Wpf.Viewport3DHelper.FindHits(this.Viewport, e.GetPosition(this.Viewport));
            ModelVisual3D clickedTextVisual = null;
            foreach (var hit in hits)
            {
                if (hit.Visual is ModelVisual3D mv3d && IsTextVisual(mv3d))
                {
                    clickedTextVisual = mv3d;
                    break;
                }
            }

            if (clickedTextVisual != null)
            {
                // A text object was clicked. Select it.
                HandleTextSelection(clickedTextVisual);

                // After selecting, check if the click also constitutes a drag start on the new adorner
                if (_textEditAdorner != null && IsPointInRotatedRect(pos, _textEditAdorner.EditRect, _textEditAdorner.RotationAngle))
                {
                    _isDraggingText = true;
                    _dragStartMousePos = e.GetPosition(this.Viewport);
                    _dragStartTextPos = _selectedTextInfo.Position;
                }
                e.Handled = true;
                return;
            }
            else
            {
                // Clicked on empty space, clear selection
                ClearTextSelection();
            }
        }


        private void helixView_MouseMove(object sender, MouseEventArgs e)
        {
            // 设置当前控件为活跃视口（节流控制）
            this.SetAsActiveControl();
            
            // 检查并尝试恢复因视口原因被隐藏的编辑框
            CheckAndRestoreEditBox();

            var pos = e.GetPosition(this);

            // 在非编辑模式下，不处理任何拖拽操作
            if (_currentEditingMode != EditingMode.Editing)
            {
                Mouse.OverrideCursor = null;
                return;
            }

            // Phase 1: Check if we should START a drag/resize/rotate gesture.
            if (e.LeftButton == MouseButtonState.Pressed && !_isDragGesture && _mouseDownPos.HasValue &&
                (_isDraggingText || _isRotating || _isResizing))
            {
                Vector delta = pos - _mouseDownPos.Value;
                if (Math.Abs(delta.X) > SystemParameters.MinimumHorizontalDragDistance ||
                    Math.Abs(delta.Y) > SystemParameters.MinimumVerticalDragDistance)
                {
                    _isDragGesture = true;
                    CaptureMouse();
                    if (_isDraggingText)
                    {
                        SetTextHighlight(true); // Highlight only when drag is confirmed
                    }
                }
            }

            // Phase 2: If a gesture is active, perform the operation.
            if (_isDragGesture)
            {
                if (_isDraggingText && _selectedTextVisual != null)
                {
                    var viewportPos = e.GetPosition(this.Viewport);
                    var hit = Viewport3DHelper.UnProject(this.Viewport, viewportPos, _dragStartTextPos, new Vector3D(0, 0, 1));
                    if (hit != null)
                    {
                        var offset = hit.Value - _dragStartTextPos;
                        MoveSelectedText(offset);
                        _dragStartTextPos = hit.Value;
                    }
                    return;
                }
                if (_isRotating && _selectedTextVisual != null)
                {
                    if (_selectedTextInfo != null)
                    {
                        RotateSelectedText(pos);
                        return;
                    }
                }
                if (_isResizing && _selectedTextVisual != null)
                {
                    if (_selectedTextInfo != null)
                    {
                        double dist0 = (_dragStartMousePos - _dragStartOppositeHandleCenter).Length;
                        double dist1 = (pos - _dragStartOppositeHandleCenter).Length;

                        if (dist0 > 1e-3)
                        {
                            double scale = dist1 / dist0;
                            double newHeight = Math.Max(1, _dragStartHeight * scale);
                            _selectedTextInfo.Height = newHeight;
                            UpdateTextVisual(_selectedTextInfo);

                            // ✅ 关键修复：同步更新DXF文档中的实体
                            SyncTextInfoToDxfEntity(_selectedTextInfo);

                            AddEditHandles(_selectedTextInfo);

                            // ✅ 新增：实时发布镜像同步事件，确保调整过程中立即同步
                            PublishMirrorSyncEvent(MirrorSyncOperation.Resize, _selectedTextInfo, _selectedTextInfo.Id);
                        }
                        return;
                    }
                }
            }

            // Phase 3: Update cursor based on hit testing (if not dragging).
            if (_currentEditingMode == EditingMode.Editing && _textEditAdorner != null && !_isDragGesture)
            {
                var rotateRect = GetRotateHandleRect();
                if (rotateRect.Contains(pos))
                {
                    Mouse.OverrideCursor = Cursors.Hand;
                }
                else
                {
                    var handleRects = GetHandleRects();
                    int onResizeIndex = -1;
                    for (int i = 0; i < handleRects.Length; i++)
                    {
                        if (handleRects[i].Contains(pos))
                        {
                            onResizeIndex = i;
                            break;
                        }
                    }

                    if (onResizeIndex >= 0)
                    {
                        // 根据编辑框旋转角度调整光标方向
                        double rotationAngle = _textEditAdorner.RotationAngle;

                        // 将角度标准化到 0-2π 范围
                        while (rotationAngle < 0) rotationAngle += 2 * Math.PI;
                        while (rotationAngle >= 2 * Math.PI) rotationAngle -= 2 * Math.PI;

                        // 0:TL, 1:TC, 2:TR, 3:MR, 4:BR, 5:BC, 6:BL, 7:ML
                        switch (onResizeIndex)
                        {
                            case 0:
                            case 4: // 对角手柄
                                // 在0°和180°时使用SizeNWSE，在90°和270°时使用SizeNESW
                                if ((rotationAngle >= 0 && rotationAngle < Math.PI / 2) ||
                                    (rotationAngle >= Math.PI && rotationAngle < 3 * Math.PI / 2))
                                    Mouse.OverrideCursor = Cursors.SizeNWSE;
                                else
                                    Mouse.OverrideCursor = Cursors.SizeNESW;
                                break;

                            case 2:
                            case 6: // 对角手柄
                                // 在0°和180°时使用SizeNESW，在90°和270°时使用SizeNWSE
                                if ((rotationAngle >= 0 && rotationAngle < Math.PI / 2) ||
                                    (rotationAngle >= Math.PI && rotationAngle < 3 * Math.PI / 2))
                                    Mouse.OverrideCursor = Cursors.SizeNESW;
                                else
                                    Mouse.OverrideCursor = Cursors.SizeNWSE;
                                break;

                            case 1:
                            case 5: // 垂直边中点
                                // 在0°和180°时使用SizeNS，在90°和270°时使用SizeWE
                                if ((rotationAngle >= 0 && rotationAngle < Math.PI / 2) ||
                                    (rotationAngle >= Math.PI && rotationAngle < 3 * Math.PI / 2))
                                    Mouse.OverrideCursor = Cursors.SizeNS;
                                else
                                    Mouse.OverrideCursor = Cursors.SizeWE;
                                break;

                            case 3:
                            case 7: // 水平边中点
                                // 在0°和180°时使用SizeWE，在90°和270°时使用SizeNS
                                if ((rotationAngle >= 0 && rotationAngle < Math.PI / 2) ||
                                    (rotationAngle >= Math.PI && rotationAngle < 3 * Math.PI / 2))
                                    Mouse.OverrideCursor = Cursors.SizeWE;
                                else
                                    Mouse.OverrideCursor = Cursors.SizeNS;
                                break;

                            default: Mouse.OverrideCursor = null; break;
                        }
                    }
                    else if (IsPointInRotatedRect(pos, _textEditAdorner.EditRect, _textEditAdorner.RotationAngle))
                    {
                        Mouse.OverrideCursor = Cursors.SizeAll;
                    }
                    else
                    {
                        Mouse.OverrideCursor = null;
                    }
                }
            }
            else if (!_isDragGesture)
            {
                Mouse.OverrideCursor = null;
            }
        }


        private void helixView_MouseUp(object sender, MouseButtonEventArgs e)
        {
            // 设置当前控件为活跃视口（节流控制）
            this.SetAsActiveControl();

            if (this.IsMouseCaptured)
            {
                ReleaseMouseCapture();
            }

            if (_isRotating)
            {
                PublishMirrorSyncEvent(MirrorSyncOperation.Rotate, _selectedTextInfo);
            }

            if (_isResizing)
            {
                PublishMirrorSyncEvent(MirrorSyncOperation.Resize, _selectedTextInfo);
            }


            SetTextHighlight(false); // 拖动结束恢复

            // Reset all gesture-related state
            _isDraggingText = false;
            _isRotating = false;
            _isResizing = false;
            _isDragGesture = false;
            _resizeHandleIndex = -1;
            _mouseDownPos = null;
        }


        private void MoveSelectedText(Vector3D offset)
        {
            if (_selectedTextInfo == null) return;

            // 添加调试信息
            System.Diagnostics.Debug.WriteLine($"=== MoveSelectedText 调试信息 ===");
            System.Diagnostics.Debug.WriteLine($"当前控件ID: {this.ControlId}");
            System.Diagnostics.Debug.WriteLine($"_selectedTextInfo.Id: '{_selectedTextInfo.Id ?? "null"}'");
            System.Diagnostics.Debug.WriteLine($"_selectedTextInfo.Text: '{_selectedTextInfo.Text ?? "null"}'");
            System.Diagnostics.Debug.WriteLine($"_selectedTextInfo.Position: {_selectedTextInfo.Position}");
            System.Diagnostics.Debug.WriteLine($"_selectedTextId: '{_selectedTextId ?? "null"}'");

            _selectedTextInfo.Position += offset;

            // ✅ 关键修复：同步更新DXF文档中的实体
            SyncTextInfoToDxfEntity(_selectedTextInfo);

            UpdateTextVisual(_selectedTextInfo);
            AddEditHandles(_selectedTextInfo); // 同步辅助元素

            // 发布镜像同步事件 - 显式传递entityId参数
            PublishMirrorSyncEvent(MirrorSyncOperation.Move, _selectedTextInfo, _selectedTextInfo.Id);
        }

        // 重新生成文字视觉对象
        private void UpdateTextVisual(TextInfo info)
        {
            if (info == null) return;

            // 查找对应的视觉对象
            ModelVisual3D targetVisual = null;

            // 策略1：通过实体ID查找视觉对象
            if (_entityVisualMap.ContainsKey(info.Id))
            {
                targetVisual = _entityVisualMap[info.Id];
            }
            // 策略2：通过镜像ID查找（基于编辑/删除操作的逻辑）
            else if (_handleMapping.ContainsKey(info.Id) && _entityVisualMap.ContainsKey(_handleMapping[info.Id]))
            {
                targetVisual = _entityVisualMap[_handleMapping[info.Id]];
            }
            // 策略3：通过反向映射查找
            else if (_reverseHandleMapping.ContainsKey(info.Id) && _entityVisualMap.ContainsKey(_reverseHandleMapping[info.Id]))
            {
                targetVisual = _entityVisualMap[_reverseHandleMapping[info.Id]];
            }
            // 策略4：通过全局镜像映射管理器查找（与编辑/删除操作保持一致）
            else if (this.ControlId == "normal")
            {
                // 当前是normal控件，尝试查找镜像实体
                string originalDocumentName = GetOriginalDocumentName(_currentDxfDocument?.Name);
                if (!string.IsNullOrEmpty(originalDocumentName))
                {
                    var mirroredHandle = MirrorEntityMappingManager.GetMirroredHandle(originalDocumentName, info.Id);
                    if (!string.IsNullOrEmpty(mirroredHandle) && _entityVisualMap.ContainsKey(mirroredHandle))
                    {
                        targetVisual = _entityVisualMap[mirroredHandle];
                        System.Diagnostics.Debug.WriteLine($"通过全局映射管理器找到镜像实体视觉对象: {info.Id} -> {mirroredHandle}");
                    }
                }
            }
            else if (this.ControlId == "mirror")
            {
                // 当前是mirror控件，尝试查找镜像实体
                // 关键修复：在mirror控件中，我们需要找到的是镜像实体的视觉对象
                // 而不是原始实体的视觉对象

                // 策略4.1：通过本地映射查找镜像实体
                if (_handleMapping.ContainsKey(info.Id))
                {
                    var mirroredId = _handleMapping[info.Id];
                    if (_entityVisualMap.ContainsKey(mirroredId))
                    {
                        targetVisual = _entityVisualMap[mirroredId];
                        System.Diagnostics.Debug.WriteLine($"通过本地映射找到镜像实体视觉对象: {info.Id} -> {mirroredId}");
                    }
                }

                // 策略4.2：如果本地映射没有找到，尝试通过全局映射管理器查找
                if (targetVisual == null)
                {
                    string documentName = _currentDxfDocument?.Name;
                    if (!string.IsNullOrEmpty(documentName))
                    {
                        // 在mirror控件中，我们需要找到镜像实体的ID
                        // 可以通过反向映射或者直接查找包含"Mirrored"的ID
                        foreach (var kvp in _entityVisualMap)
                        {
                            if (kvp.Key.Contains("Mirrored") && kvp.Key.Contains(info.Id.Replace("Text_", "").Replace("Line_", "").Replace("Arc_", "").Replace("MText_", "")))
                            {
                                targetVisual = kvp.Value;
                                System.Diagnostics.Debug.WriteLine($"通过ID模式匹配找到镜像实体视觉对象: {info.Id} -> {kvp.Key}");
                                break;
                            }
                        }
                    }
                }
            }
            // 策略5：通过选中的视觉对象
            else if (_selectedTextVisual != null && _selectedTextId == info.Id)
            {
                targetVisual = _selectedTextVisual;
            }

            if (targetVisual == null)
            {
                System.Diagnostics.Debug.WriteLine($"UpdateTextVisual: 无法找到实体 {info.Id} 对应的视觉对象");
                System.Diagnostics.Debug.WriteLine($"当前控件ID: {this.ControlId}");
                System.Diagnostics.Debug.WriteLine($"_entityVisualMap数量: {_entityVisualMap.Count}");
                System.Diagnostics.Debug.WriteLine($"_handleMapping数量: {_handleMapping.Count}");
                System.Diagnostics.Debug.WriteLine($"_reverseHandleMapping数量: {_reverseHandleMapping.Count}");

                // 显示一些映射示例
                var sampleMappings = _entityVisualMap.Take(5).ToList();
                foreach (var mapping in sampleMappings)
                {
                    System.Diagnostics.Debug.WriteLine($"  映射示例: {mapping.Key} -> {mapping.Value?.GetType().Name ?? "null"}");
                }
                return;
            }

            System.Diagnostics.Debug.WriteLine($"UpdateTextVisual: 找到实体 {info.Id} 对应的视觉对象");
            System.Diagnostics.Debug.WriteLine($"当前控件ID: {this.ControlId}");
            System.Diagnostics.Debug.WriteLine($"目标视觉对象Tag: {targetVisual.GetValue(FrameworkElement.TagProperty)}");

            var parent = VisualTreeHelper.GetParent(targetVisual) as ModelVisual3D;
            if (parent != null)
            {
                parent.Children.Remove(targetVisual);
                ModelVisual3D newVisual = null;

                // 根据原始实体类型创建相应的视觉对象，使用镜像变换管理器
                // 关键修复：在mirror控件中，如果OriginalEntity为null，根据ID前缀判断实体类型
                if (info.OriginalEntity is Text text || (this.ControlId == "mirror" && info.Id.StartsWith("Text_")))
                {
                    newVisual = GetMirrorTransformManager().CreateMirrorTextVisual(
                        info.Text,
                        new SolidColorBrush(info.Color),
                        true,
                        info.Height,
                        info.Position,
                        info.Rotation,
                        "Cascadia Code",
                        info.Underline,
                        info.Rotation  // 传入当前角度作为原始角度
                    );
                    System.Diagnostics.Debug.WriteLine($"在mirror控件中创建Text视觉对象: {info.Id}");
                }
                else if (info.OriginalEntity is MText mText || (this.ControlId == "mirror" && info.Id.StartsWith("MText_")))
                {
                    newVisual = GetMirrorTransformManager().CreateMirrorMTextVisual(
                        info.Text,
                        new SolidColorBrush(info.Color),
                        false,
                        info.Height,
                        info.Position,
                        info.Rotation,
                        new Vector3D(0, 0, 0),
                        "Cascadia Code Light",
                        info.Underline
                    );
                    System.Diagnostics.Debug.WriteLine($"在mirror控件中创建MText视觉对象: {info.Id}");
                }
                else
                {
                    System.Diagnostics.Debug.WriteLine($"警告: 无法确定实体类型，OriginalEntity: {info.OriginalEntity?.GetType().Name ?? "null"}, ID: {info.Id}");
                }

                if (newVisual != null)
                {
                    // 关键修复：在mirror控件中，需要确保视觉对象被映射到正确的ID
                    string mappingKey = info.Id;

                    if (this.ControlId == "mirror")
                    {
                        // 在mirror控件中，传入的info.Id应该已经是镜像实体的ID
                        // 所以直接使用它作为映射键，不需要额外的查找逻辑
                        System.Diagnostics.Debug.WriteLine($"在mirror控件中，直接使用传入的ID作为映射键: {info.Id}");

                        // 验证：确保这个ID确实包含"Mirrored"前缀
                        if (!info.Id.Contains("Mirrored"))
                        {
                            System.Diagnostics.Debug.WriteLine($"警告: 在mirror控件中，传入的ID不包含'Mirrored'前缀: {info.Id}");
                        }
                    }

                    newVisual.SetValue(FrameworkElement.TagProperty, mappingKey);
                    parent.Children.Add(newVisual);

                    // 更新映射关系 - 使用正确的映射键
                    _entityVisualMap[mappingKey] = newVisual;
                    System.Diagnostics.Debug.WriteLine($"更新视觉对象映射: {mappingKey} -> {newVisual}");

                    // 如果是当前选中的实体，也要更新选中状态
                    if (_selectedTextId == info.Id || _selectedTextId == mappingKey)
                    {
                        _selectedTextVisual = newVisual;
                    }
                }
            }
        }

        private void helixView_MouseRightDown(object sender, MouseButtonEventArgs e)
        {
            // 设置当前控件为活跃视口（节流控制）
            this.SetAsActiveControl();

            var pos = e.GetPosition(this.Viewport);

            // 使用HelixToolkit的命中检测功能
            var hits = Viewport3DHelper.FindHits(this.Viewport, pos);

            // 查找文字对象
            ModelVisual3D clickedTextVisual = null;
            foreach (var hit in hits)
            {
                if (hit.Visual is ModelVisual3D mv3d && IsTextVisual(mv3d))
                {
                    clickedTextVisual = mv3d;
                    break;
                }
            }

            // 如果右键点击的是文字对象，显示右键菜单
            if (clickedTextVisual != null)
            {
                // 如果点击的不是当前选中的文字，先选中它
                if (_selectedTextVisual != clickedTextVisual)
                {
                    HandleTextSelection(clickedTextVisual);
                }

                // 显示右键菜单
                // ShowTextContextMenu(pos);

                e.Handled = true;
            }
        }

        /// <summary>
        /// 删除选中的文字
        /// </summary>
        private void DeleteSelectedText()
        {
            if (_selectedTextVisual == null || string.IsNullOrEmpty(_selectedTextId)) return;

            System.Diagnostics.Debug.WriteLine($"=== 开始删除选中的文字 ===");
            System.Diagnostics.Debug.WriteLine($"当前控件ID: {this.ControlId}");
            System.Diagnostics.Debug.WriteLine($"选中的文字ID: {_selectedTextId}");
            System.Diagnostics.Debug.WriteLine($"选中的文字信息: {_selectedTextInfo?.Text ?? "null"}");

            // 获取文字信息
            var textInfo = _selectedTextInfo;
            string entityIdToDelete = _selectedTextId; // 保存要删除的实体ID

            System.Diagnostics.Debug.WriteLine($"要删除的实体ID: {entityIdToDelete}");

            // 从DXF文档中删除实体（如果有的话）
            if (_currentDxfDocument != null && textInfo?.OriginalEntity != null)
            {
                _currentDxfDocument.Entities.Remove(textInfo.OriginalEntity);
                System.Diagnostics.Debug.WriteLine($"从DXF文档中删除实体: {textInfo.Text}");
            }

            //从父容器中移除文字视觉对象
            var parent = VisualTreeHelper.GetParent(_selectedTextVisual) as ModelVisual3D;
            if (parent != null)
            {
                parent.Children.Remove(_selectedTextVisual);
                System.Diagnostics.Debug.WriteLine($"从父容器中移除视觉对象");
            }

            // 从文字信息映射中移除
            _textInfoMap.Remove(_selectedTextId);
            System.Diagnostics.Debug.WriteLine($"从_textInfoMap中移除实体: {_selectedTextId}");

            // 清除选中状态
            ClearTextSelection();
            System.Diagnostics.Debug.WriteLine($"清除选中状态");

            // 发布删除事件通知
            if (textInfo != null)
            {
                _eventAggregatorInstance.GetEvent<AnnotationDeletedEvent>().Publish(new AnnotationDeletedEventArgs
                {
                    ControlId = this.ControlId,
                    TextInfo = textInfo
                });

                // 发布镜像同步事件 - 使用保存的实体ID
                System.Diagnostics.Debug.WriteLine($"准备发布镜像同步删除事件，实体ID: {entityIdToDelete}");
                System.Diagnostics.Debug.WriteLine($"当前控件ID: {this.ControlId}");
                System.Diagnostics.Debug.WriteLine($"目标控件ID: {(this.ControlId == "normal" ? "mirror" : "normal")}");
                PublishMirrorSyncEvent(MirrorSyncOperation.Delete, null, entityIdToDelete);
            }

            System.Diagnostics.Debug.WriteLine($"=== 删除选中的文字完成 ===");
        }

        /// <summary>
        /// 获取当前选中的文字信息
        /// </summary>
        /// <returns>选中的文字信息，如果没有选中则返回null</returns>
        public TextInfo GetSelectedTextInfo()
        {
            return _selectedTextInfo;
        }


        /// <summary>
        /// 更新选中文字的内容
        /// </summary>
        /// <param name="newText">新的文字内容</param>
        private void UpdateSelectedText(string newText)
        {
            if (_selectedTextInfo == null)
                return;

            // 添加调试信息
            System.Diagnostics.Debug.WriteLine($"=== UpdateSelectedText 调试信息 ===");
            System.Diagnostics.Debug.WriteLine($"当前控件ID: {this.ControlId}");
            System.Diagnostics.Debug.WriteLine($"_selectedTextInfo.Id: '{_selectedTextInfo.Id ?? "null"}'");
            System.Diagnostics.Debug.WriteLine($"_selectedTextInfo.Text: '{_selectedTextInfo.Text ?? "null"}' -> '{newText}'");
            System.Diagnostics.Debug.WriteLine($"_selectedTextId: '{_selectedTextId ?? "null"}'");

            _selectedTextInfo.Text = newText;

            // ✅ 关键修复：同步更新DXF文档中的实体
            SyncTextInfoToDxfEntity(_selectedTextInfo);

            // 重新创建文字视觉对象  
            if (_selectedTextVisual != null)
            {
                // 使用 Children 属性直接移除旧的文字视觉对象  
                var parent = VisualTreeHelper.GetParent(_selectedTextVisual) as ModelVisual3D;
                if (parent != null)
                {
                    parent.Children.Remove(_selectedTextVisual);
                }
                else
                {
                    // 如果是直接添加到控件的，从控件中移除
                    this.Children.Remove(_selectedTextVisual);
                }

                // 创建新的文字视觉对象  
                ModelVisual3D newTextVisual = null;
                if (_selectedTextInfo.OriginalEntity is Text text)
                {
                    newTextVisual = GetTextVisual(
                        newText,
                        new SolidColorBrush(ConvertDxfColor(text.Color, text.Layer)),
                        false,
                        _selectedTextInfo.Height,
                        _selectedTextInfo.Position,
                        new Vector3D(1, 0, 0),
                        new Vector3D(0, 1, 0),
                        _selectedTextInfo.Rotation,
                        "Cascadia Code",
                        _selectedTextInfo.Underline
                    );
                }
                else if (_selectedTextInfo.OriginalEntity is MText mText)
                {
                    newTextVisual = GetMTextVisual(
                        newText,
                        new SolidColorBrush(ConvertDxfColor(mText.Color, mText.Layer)),
                        false,
                        _selectedTextInfo.Height,
                        _selectedTextInfo.Position,
                        new Vector3D(1, 0, 0),
                        new Vector3D(0, 1, 0),
                        _selectedTextInfo.Rotation,
                        new Vector3D(0, 0, 0),
                        "Cascadia Code Light",
                        _selectedTextInfo.Underline
                    );
                }
                else
                {
                    // 如果没有OriginalEntity（新增的标注），使用默认设置
                    newTextVisual = GetTextVisual(
                        newText,
                        new SolidColorBrush(_selectedTextInfo.Color),
                        false,
                        _selectedTextInfo.Height,
                        _selectedTextInfo.Position,
                        new Vector3D(1, 0, 0),
                        new Vector3D(0, 1, 0),
                        _selectedTextInfo.Rotation,
                        "Cascadia Code",
                        _selectedTextInfo.Underline
                    );
                }

                if (newTextVisual != null)
                {
                    // 设置相同的标识  
                    newTextVisual.SetValue(FrameworkElement.TagProperty, _selectedTextId);

                    // 添加到适当的父容器  
                    if (parent != null)
                    {
                        parent.Children.Add(newTextVisual);
                    }
                    else
                    {
                        this.Children.Add(newTextVisual);
                    }

                    // 更新映射和选中状态  
                    _annotationModels[_selectedTextId] = newTextVisual;
                    _selectedTextVisual = newTextVisual;

                    // ✅ 关键修复：更新实体视觉映射表
                    // 移除旧的映射（如果存在）
                    if (_entityVisualMap.ContainsKey(_selectedTextInfo.Id))
                    {
                        _entityVisualMap.Remove(_selectedTextInfo.Id);
                    }
                    // 添加新的映射
                    _entityVisualMap[_selectedTextInfo.Id] = newTextVisual;
                    System.Diagnostics.Debug.WriteLine($"UpdateSelectedText: 更新实体视觉映射 {_selectedTextInfo.Id} -> newTextVisual");

                    // 应用高亮  
                    HighlightSelectedText(newTextVisual);
                }

                // 发布镜像同步事件 - 显式传递entityId参数
                PublishMirrorSyncEvent(MirrorSyncOperation.Edit, _selectedTextInfo, _selectedTextInfo.Id);
            }
        }

        private void OnDeleteTextEdit()
        {
            DeleteSelectedText();
            // 移除ShowTextEditPanel相关代码
        }

        /// <summary>
        /// 处理镜像同步事件
        /// </summary>
        /// <param name="args">镜像同步事件参数</param>
        public void OnMirrorSync(MirrorSyncEventArgs args)
        {
            System.Diagnostics.Debug.WriteLine($"=== 收到镜像同步事件 ===");
            System.Diagnostics.Debug.WriteLine($"事件操作: {args.Operation}");
            System.Diagnostics.Debug.WriteLine($"源控件ID: {args.SourceControlId}");
            System.Diagnostics.Debug.WriteLine($"目标控件ID: {args.TargetControlId}");
            System.Diagnostics.Debug.WriteLine($"当前控件ID: '{this.ControlId ?? "null"}'");
            System.Diagnostics.Debug.WriteLine($"当前控件ID类型: {this.ControlId?.GetType().Name ?? "null"}");
            System.Diagnostics.Debug.WriteLine($"实体ID: {args.EntityId}");
            System.Diagnostics.Debug.WriteLine($"文字信息: {args.TextInfo?.Text ?? "null"}");

            // 添加详细的TextInfo调试信息
            if (args.TextInfo != null)
            {
                System.Diagnostics.Debug.WriteLine($"接收到的TextInfo详细信息:");
                System.Diagnostics.Debug.WriteLine($"  Id: '{args.TextInfo.Id ?? "null"}'");
                System.Diagnostics.Debug.WriteLine($"  Text: '{args.TextInfo.Text ?? "null"}'");
                System.Diagnostics.Debug.WriteLine($"  Position: ({args.TextInfo.PositionX}, {args.TextInfo.PositionY}, {args.TextInfo.PositionZ})");
                System.Diagnostics.Debug.WriteLine($"  Height: {args.TextInfo.Height}");
                System.Diagnostics.Debug.WriteLine($"  Rotation: {args.TextInfo.Rotation}");
                System.Diagnostics.Debug.WriteLine($"  LayerName: '{args.TextInfo.LayerName ?? "null"}'");
                System.Diagnostics.Debug.WriteLine($"  Color: ({args.TextInfo.ColorR}, {args.TextInfo.ColorG}, {args.TextInfo.ColorB}, {args.TextInfo.ColorA})");
                System.Diagnostics.Debug.WriteLine($"  Underline: {args.TextInfo.Underline}");
            }

            // 添加控件ID匹配检查
            System.Diagnostics.Debug.WriteLine($"控件ID匹配检查:");
            System.Diagnostics.Debug.WriteLine($"  目标控件ID: '{args.TargetControlId}'");
            System.Diagnostics.Debug.WriteLine($"  当前控件ID: '{this.ControlId}'");
            System.Diagnostics.Debug.WriteLine($"  目标控件ID类型: {args.TargetControlId?.GetType().Name ?? "null"}");
            System.Diagnostics.Debug.WriteLine($"  当前控件ID类型: {this.ControlId?.GetType().Name ?? "null"}");
            System.Diagnostics.Debug.WriteLine($"  字符串比较结果: {string.Equals(args.TargetControlId, this.ControlId, StringComparison.Ordinal)}");
            System.Diagnostics.Debug.WriteLine($"  是否匹配: {args.TargetControlId == this.ControlId}");

            // 只处理发送给当前控件的事件
            if (args.TargetControlId != this.ControlId)
            {
                System.Diagnostics.Debug.WriteLine($"事件目标不匹配，跳过处理");
                System.Diagnostics.Debug.WriteLine($"=== 镜像同步事件处理跳过 ===");
                return;
            }

            // 防止循环同步
            if (args.SourceControlId == this.ControlId)
            {
                System.Diagnostics.Debug.WriteLine($"防止循环同步，跳过处理");
                System.Diagnostics.Debug.WriteLine($"=== 镜像同步事件处理跳过 ===");
                return;
            }

            // 改进的重复事件检测：对于移动操作，允许处理位置变化
            bool shouldSkip = false;
            string eventKey = GenerateEventKey(args.Operation, args.SourceControlId, args.TargetControlId, args.EntityId, args.TextInfo);
            System.Diagnostics.Debug.WriteLine($"生成的事件Key: '{eventKey}'");
            System.Diagnostics.Debug.WriteLine($"TextInfo?.Id: '{args.TextInfo?.Id ?? "null"}'");
            System.Diagnostics.Debug.WriteLine($"EntityId: '{args.EntityId ?? "null"}'");

            if (args.Operation == MirrorSyncOperation.Move && args.TextInfo != null)
            {
                // 对于移动操作，检查是否真的是重复事件（相同位置）
                if (_processedMirrorSyncEvents.Contains(eventKey))
                {
                    // 检查位置是否有实际变化
                    var lastProcessedInfo = GetLastProcessedMoveInfo(args.EntityId);
                    if (lastProcessedInfo != null)
                    {
                        double positionDelta = Math.Abs(lastProcessedInfo.Position.X - args.TextInfo.PositionX) +
                                               Math.Abs(lastProcessedInfo.Position.Y - args.TextInfo.PositionY);
                        if (positionDelta < 0.001) // 位置变化很小，认为是重复事件
                        {
                            shouldSkip = true;
                            System.Diagnostics.Debug.WriteLine($"移动操作位置变化很小 ({positionDelta:F6})，跳过处理");
                        }
                        else
                        {
                            System.Diagnostics.Debug.WriteLine($"移动操作位置有明显变化 ({positionDelta:F6})，允许处理");
                            // 更新最后处理的位置信息
                            UpdateLastProcessedMoveInfo(args.EntityId, args.TextInfo);
                        }
                    }
                    else
                    {
                        // 没有历史记录，允许处理
                        System.Diagnostics.Debug.WriteLine($"移动操作无历史记录，允许处理");
                        UpdateLastProcessedMoveInfo(args.EntityId, args.TextInfo);
                    }
                }
                else
                {
                    // 新的事件，允许处理
                    System.Diagnostics.Debug.WriteLine($"移动操作新事件，允许处理");
                    UpdateLastProcessedMoveInfo(args.EntityId, args.TextInfo);
                }
            }
            else if (args.Operation == MirrorSyncOperation.Resize && args.TextInfo != null)
            {
                // 对于调整大小操作，检查是否真的是重复事件（相同高度）
                if (_processedMirrorSyncEvents.Contains(eventKey))
                {
                    // 检查高度是否有实际变化
                    var lastProcessedInfo = GetLastProcessedMoveInfo(args.TextInfo?.Id);
                    if (lastProcessedInfo != null)
                    {
                        double heightDelta = Math.Abs(lastProcessedInfo.Height - args.TextInfo.Height);
                        if (heightDelta < 0.001) // 高度变化很小，认为是重复事件
                        {
                            shouldSkip = true;
                            System.Diagnostics.Debug.WriteLine($"调整大小操作高度变化很小 ({heightDelta:F6})，跳过处理");
                        }
                        else
                        {
                            System.Diagnostics.Debug.WriteLine($"调整大小操作高度有明显变化 ({heightDelta:F6})，允许处理");
                            // 更新最后处理的位置信息
                            UpdateLastProcessedMoveInfo(args.TextInfo?.Id, args.TextInfo);
                        }
                    }
                    else
                    {
                        // 没有历史记录，允许处理
                        System.Diagnostics.Debug.WriteLine($"调整大小操作无历史记录，允许处理");
                        UpdateLastProcessedMoveInfo(args.TextInfo?.Id, args.TextInfo);
                    }
                }
                else
                {
                    // 新的事件，允许处理
                    System.Diagnostics.Debug.WriteLine($"调整大小操作新事件，允许处理");
                    UpdateLastProcessedMoveInfo(args.TextInfo?.Id, args.TextInfo);
                }
            }
            else
            {
                // 其他操作，使用原有的重复检测逻辑
                shouldSkip = _processedMirrorSyncEvents.Contains(eventKey);
            }

            if (shouldSkip)
            {
                System.Diagnostics.Debug.WriteLine($"重复事件，跳过处理: {eventKey}");
                return;
            }

            // 添加到已处理事件集合
            _processedMirrorSyncEvents.Add(eventKey);

            // 限制集合大小，防止内存泄漏
            if (_processedMirrorSyncEvents.Count > 1000)
            {
                var oldestEvents = _processedMirrorSyncEvents.Take(500).ToList();
                foreach (var oldEvent in oldestEvents)
                {
                    _processedMirrorSyncEvents.Remove(oldEvent);
                }
                System.Diagnostics.Debug.WriteLine($"清理了 {oldestEvents.Count} 个旧事件记录");
            }

            try
            {
                System.Diagnostics.Debug.WriteLine($"开始处理镜像同步事件: {args.Operation}");
                switch (args.Operation)
                {
                    case MirrorSyncOperation.Add:
                        System.Diagnostics.Debug.WriteLine($"处理添加操作");
                        SyncAddEntity(args.TextInfo?.ToTextInfo());
                        break;
                    case MirrorSyncOperation.Edit:
                    case MirrorSyncOperation.Move:
                    case MirrorSyncOperation.Rotate:
                    case MirrorSyncOperation.Resize:
                        System.Diagnostics.Debug.WriteLine($"处理编辑操作");
                        SyncEditEntity(args.TextInfo?.ToTextInfo());
                        break;
                    case MirrorSyncOperation.Delete:
                        System.Diagnostics.Debug.WriteLine($"处理删除操作");
                        SyncDeleteEntity(args.EntityId);
                        break;
                        //case MirrorSyncOperation.Move:
                        //    System.Diagnostics.Debug.WriteLine($"处理移动操作");
                        //    SyncMoveEntity(args.TextInfo?.ToTextInfo());
                        //    break;
                        //case MirrorSyncOperation.Rotate:
                        //    System.Diagnostics.Debug.WriteLine($"处理旋转操作");
                        //    SyncRotateEntity(args.TextInfo?.ToTextInfo());
                        //    break;
                }
                System.Diagnostics.Debug.WriteLine($"镜像同步事件处理完成: {args.Operation}");

                // 同步相机视图（可选功能，优先级较低）
                SyncCameraViewIfNeeded(args.SourceControlId);
            }
            catch (Exception ex)
            {
                // 记录错误但不中断程序
                System.Diagnostics.Debug.WriteLine($"镜像同步失败: {ex.Message}");
                System.Diagnostics.Debug.WriteLine($"异常堆栈: {ex.StackTrace}");
            }

            System.Diagnostics.Debug.WriteLine($"=== 镜像同步事件处理完成 ===");
        }

        /// <summary>
        /// 生成事件键，包含位置信息以区分连续的移动操作
        /// </summary>
        private string GenerateEventKey(MirrorSyncOperation operation, object sourceControlId, object targetControlId, string entityId, TextInfoSync textInfoSync)
        {
            var baseKey = $"{operation}_{sourceControlId}_{targetControlId}_{entityId}";

            // 对于移动操作，添加位置信息以区分不同的位置
            if (operation == MirrorSyncOperation.Move && textInfoSync != null)
            {
                var positionKey = $"_{textInfoSync.PositionX:F3}_{textInfoSync.PositionY:F3}";
                return baseKey + positionKey;
            }
            else if (operation == MirrorSyncOperation.Rotate && textInfoSync != null)
            {
                var angleKey = $"_{textInfoSync.Rotation:F3}";
                return baseKey + angleKey;
            }
            else if (operation == MirrorSyncOperation.Resize && textInfoSync != null)
            {
                var heightKey = $"_{textInfoSync.Height:F3}";
                return baseKey + heightKey;
            }

            return baseKey;
        }

        /// <summary>
        /// 获取最后处理的移动信息
        /// </summary>
        private TextInfo GetLastProcessedMoveInfo(string entityId)
        {
            if (!string.IsNullOrEmpty(entityId) && _lastProcessedMoveInfo.ContainsKey(entityId))
            {
                return _lastProcessedMoveInfo[entityId];
            }
            return null;
        }

        /// <summary>
        /// 更新最后处理的移动信息
        /// </summary>
        private void UpdateLastProcessedMoveInfo(string entityId, TextInfoSync textInfoSync)
        {
            if (textInfoSync != null && !string.IsNullOrEmpty(entityId))
            {
                var textInfo = textInfoSync.ToTextInfo();
                _lastProcessedMoveInfo[entityId] = textInfo;
            }
        }

        // 屏幕坐标转换辅助
        private Point Point3DToScreen(Point3D pt)
        {
            var matrix = Viewport3DHelper.GetTotalTransform(this.Viewport);
            var p = matrix.Transform(pt);
            return new Point(p.X, p.Y);
        }

        // 设置文字高亮（橙色）或恢复原色
        private void SetTextHighlight(bool highlight)
        {
            if (_selectedTextId != null && _textInfoMap.ContainsKey(_selectedTextId))
            {
                var info = _textInfoMap[_selectedTextId];
                if (highlight)
                {
                    //TODO: 临时去掉高亮效果
                    //_originalTextBrush = new SolidColorBrush(info.Color);
                    //info.Color = Colors.Orange;
                }
                else if (_originalTextBrush != null)
                {
                    var solid = _originalTextBrush as SolidColorBrush;
                    info.Color = solid != null ? solid.Color : Colors.Cyan;
                }
                UpdateTextVisual(info);
                AddEditHandles(info);
            }
        }

        // 新增：Helper methods for 2D handle calculations
        private Rect[] GetHandleRects()
        {
            if (_textEditAdorner == null) return new Rect[0];

            var rect = _textEditAdorner.EditRect;
            double hs = _textEditAdorner.HandleSize;
            double rotationAngle = _textEditAdorner.RotationAngle;
            var rotationCenter = _textEditAdorner.RotationCenter;

            // 计算0度时的8个手柄位置（相对于旋转中心）
            var halfWidth = rect.Width / 2;
            var halfHeight = rect.Height / 2;

            // 计算编辑框中心相对于旋转中心的偏移
            var rectCenter = new Point(rect.X + rect.Width / 2, rect.Y + rect.Height / 2);
            var centerOffset = new Point(rectCenter.X - rotationCenter.X, rectCenter.Y - rotationCenter.Y);

            var unrotatedHandles = new Point[] {
                new Point(-halfWidth, -halfHeight), // 0: TL
                new Point(0, -halfHeight), // 1: TC
                new Point(halfWidth, -halfHeight), // 2: TR
                new Point(halfWidth, 0), // 3: MR
                new Point(halfWidth, halfHeight), // 4: BR
                new Point(0, halfHeight), // 5: BC
                new Point(-halfWidth, halfHeight), // 6: BL
                new Point(-halfWidth, 0)  // 7: ML
            };

            // 旋转每个手柄位置
            var rotatedHandles = new Point[8];
            for (int i = 0; i < 8; i++)
            {
                var handle = unrotatedHandles[i];
                double cos = Math.Cos(rotationAngle); // 使用正角度以匹配文字旋转方向
                double sin = Math.Sin(rotationAngle);

                // 先计算手柄相对于编辑框中心的位置
                var handleRelativeToRectCenter = new Point(handle.X + centerOffset.X, handle.Y + centerOffset.Y);

                // 然后旋转
                double rotatedX = handleRelativeToRectCenter.X * cos - handleRelativeToRectCenter.Y * sin;
                double rotatedY = handleRelativeToRectCenter.X * sin + handleRelativeToRectCenter.Y * cos;

                rotatedHandles[i] = new Point(rotationCenter.X + rotatedX, rotationCenter.Y + rotatedY);
            }

            // 为每个手柄增加扩展区域以提高灵敏度
            return rotatedHandles.Select(p => new Rect(p.X - hs / 2 - _resizeHandleExpansion,
                                                       p.Y - hs / 2 - _resizeHandleExpansion,
                                                       hs + _resizeHandleExpansion * 2,
                                                       hs + _resizeHandleExpansion * 2)).ToArray();
        }

        private Rect GetRotateHandleRect()
        {
            if (_textEditAdorner == null) return Rect.Empty;

            // 使用 Adorner 提供的精确边界，并适当扩大检测区域以提高灵敏度
            var bounds = _textEditAdorner.RotateHandleBounds;
            if (bounds.IsEmpty) return Rect.Empty;

            // 考虑编辑框的旋转角度，旋转手柄的检测区域
            double rotationAngle = _textEditAdorner.RotationAngle;
            var rotationCenter = _textEditAdorner.RotationCenter;
            var halfWidth = bounds.Width / 2;
            var halfHeight = bounds.Height / 2;

            // 计算旋转手柄中心相对于旋转中心的偏移
            var boundsCenter = new Point(bounds.X + bounds.Width / 2, bounds.Y + bounds.Height / 2);
            var centerOffset = new Point(boundsCenter.X - rotationCenter.X, boundsCenter.Y - rotationCenter.Y);

            // 计算旋转后的边界
            double cos = Math.Cos(rotationAngle); // 使用正角度以匹配文字旋转方向
            double sin = Math.Sin(rotationAngle);

            // 计算四个角点的旋转位置
            var corners = new Point[] {
                new Point(-halfWidth, -halfHeight),
                new Point(halfWidth, -halfHeight),
                new Point(halfWidth, halfHeight),
                new Point(-halfWidth, halfHeight)
            };

            var rotatedCorners = corners.Select(corner =>
            {
                // 先计算角点相对于旋转手柄中心的位置
                var cornerRelativeToHandleCenter = new Point(corner.X + centerOffset.X, corner.Y + centerOffset.Y);

                // 然后旋转
                double rotatedX = cornerRelativeToHandleCenter.X * cos - cornerRelativeToHandleCenter.Y * sin;
                double rotatedY = cornerRelativeToHandleCenter.X * sin + cornerRelativeToHandleCenter.Y * cos;

                return new Point(rotationCenter.X + rotatedX, rotationCenter.Y + rotatedY);
            }).ToArray();

            // 计算旋转后的边界框
            double minX = rotatedCorners.Min(p => p.X);
            double minY = rotatedCorners.Min(p => p.Y);
            double maxX = rotatedCorners.Max(p => p.X);
            double maxY = rotatedCorners.Max(p => p.Y);

            // 使用配置的扩展像素，使检测区域更容易被鼠标命中
            return new Rect(minX - _rotateHandleExpansion, minY - _rotateHandleExpansion,
                           maxX - minX + _rotateHandleExpansion * 2, maxY - minY + _rotateHandleExpansion * 2);
        }

        private void OnCameraChanged(object sender, RoutedEventArgs e)
        {
            if (_selectedTextInfo != null)
            {
                // 检查编辑框是否应该显示
                if (ShouldShowEditBox())
                {
                    // 如果编辑框应该显示，重新创建编辑手柄
                    AddEditHandles(_selectedTextInfo); // Re-create the adorner with updated projection
                }
                else
                {
                    // 如果编辑框不应该显示，移除编辑手柄
                    RemoveEditHandles();
                    _isEditBoxVisible = false;
                    _editBoxWasHiddenDueToViewport = true;
                }
            }

            // 在编辑模式下，使用更积极的相机同步策略，确保视图一致性
            if (_currentEditingMode != EditingMode.None)
            {
                // 编辑模式下，减少节流时间，确保实时同步
                var now = DateTime.Now.Ticks / 10000; // 毫秒
                if (_lastCameraChangeTime > 0 && (now - _lastCameraChangeTime) < 50) // 编辑模式下使用50ms节流
                {
                    return;
                }
                _lastCameraChangeTime = now;

                // 编辑模式下优先同步缩放，确保视图一致性
                try
                {
                    _isProcessingCameraSync = true;

                    // 使用优化的编辑模式相机同步
                    OptimizeCameraSyncForEditing(this.ControlId);

                    System.Diagnostics.Debug.WriteLine($"编辑模式下相机同步完成: {this.ControlId}");
                }
                catch (Exception ex)
                {
                    System.Diagnostics.Debug.WriteLine($"编辑模式下相机同步异常: {ex.Message}");
                }
                finally
                {
                    _isProcessingCameraSync = false;
                }
                return;
            }

            // 非编辑模式下的正常相机同步逻辑
            var normalNow = DateTime.Now.Ticks / 10000; // 毫秒
            if (_lastCameraChangeTime > 0 && (normalNow - _lastCameraChangeTime) < CAMERA_SYNC_THROTTLE_MS)
            {
                //System.Diagnostics.Debug.WriteLine($"相机变化节流：距离上次变化 {normalNow - _lastCameraChangeTime}ms < {CAMERA_SYNC_THROTTLE_MS}ms，跳过同步");
                return;
            }
            _lastCameraChangeTime = normalNow;

            // 防止循环同步
            if (_isProcessingCameraSync)
            {
                //System.Diagnostics.Debug.WriteLine("相机同步正在进行中，跳过本次同步");
                return;
            }

            try
            {
                _isProcessingCameraSync = true;

                // 智能相机同步（自动检测变化类型）
                this.SmartCameraSync(this.ControlId, CameraSyncExtensions.CameraChangeType.Multiple);

                System.Diagnostics.Debug.WriteLine($"相机同步完成: {this.ControlId}");
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine($"相机同步异常: {ex.Message}");
            }
            finally
            {
                _isProcessingCameraSync = false;
            }
        }

        private void RotateSelectedText(Point mousePos)
        {
            if (_selectedTextInfo == null || _textEditAdorner == null) return;

            // 使用文字左下角作为旋转中心
            var textBottomLeft = _selectedTextInfo.Position;
            var rotateCenter = Point3DToScreen(textBottomLeft);

            // 计算鼠标相对于旋转中心的角度
            double currentAngle = Math.Atan2(mousePos.Y - rotateCenter.Y, mousePos.X - rotateCenter.X);

            // 计算角度差（鼠标顺时针移动，文字顺时针旋转）
            double angleDiff = currentAngle - _rotateStartAngle;

            // 处理角度跨越 -π 到 π 边界的情况
            if (angleDiff > Math.PI) angleDiff -= 2 * Math.PI;
            if (angleDiff < -Math.PI) angleDiff += 2 * Math.PI;

            // 转换为度数并更新文字旋转角度
            double rotationDelta = angleDiff * 180 / Math.PI;

            // 反转旋转方向
            rotationDelta = -rotationDelta;

            _selectedTextInfo.Rotation += rotationDelta;

            // 限制角度范围
            while (_selectedTextInfo.Rotation > 360) _selectedTextInfo.Rotation -= 360;
            while (_selectedTextInfo.Rotation < 0) _selectedTextInfo.Rotation += 360;

            _rotateStartAngle = currentAngle;

            // 更新3D文字
            UpdateTextVisual(_selectedTextInfo);

            // ✅ 关键修复：同步更新DXF文档中的实体
            SyncTextInfoToDxfEntity(_selectedTextInfo);

            // 重新计算编辑框位置，保持大小不变
            AddEditHandles(_selectedTextInfo);

        }

        // DXF文档引用，用于保存新增标注
        private DxfDocument _currentDxfDocument;

        // 预览模式标注管理
        private string _previewAnnotationId;
        private ModelVisual3D _previewTextVisual;
        private bool _isInPreviewMode = false;

        /// <summary>
        /// 设置当前的DXF文档引用
        /// </summary>
        /// <param name="document">DXF文档</param>
        public void SetCurrentDxfDocument(DxfDocument document)
        {
            _currentDxfDocument = document;

            // ✅ 关键修复：注册到AnnotationManager
            if (document != null)
            {
                var annotationManager = AnnotationManager.Instance;
                annotationManager.RegisterEditingDocument(this.ControlId, document);
                System.Diagnostics.Debug.WriteLine($"已注册编辑文档到AnnotationManager: {this.ControlId} -> {document.Name}");
            }
        }

        /// <summary>
        /// 创建预览标注（不立即添加到DXF文档）
        /// </summary>
        /// <param name="mousePos">鼠标位置</param>
        private void CreatePreviewAnnotation(Point mousePos)
        {
            // 如果已有预览标注，先清除
            ClearPreviewAnnotation();

            // 计算3D世界坐标
            Point3D? hitPoint = HelixToolkit.Wpf.Viewport3DHelper.UnProject(this.Viewport, mousePos, new Point3D(0, 0, 1), new Vector3D(0, 0, 1));
            var worldPos = hitPoint ?? new Point3D(mousePos.X / 10.0, mousePos.Y / 10.0, 0);

            // 创建预览标注ID
            _previewAnnotationId = "Text_PREVIEW_" + Guid.NewGuid().ToString();

            // 从全局配置中获取印字层颜色
            Color annotationColor = GetAnnotationColorFromConfig();

            // 创建预览文字信息
            var previewTextInfo = new TextInfo
            {
                Id = _previewAnnotationId,
                Text = "输入标注内容", // 默认占位文字
                Position = new Point3D(worldPos.X, worldPos.Y, 0),
                Height = 5.0, // 默认高度
                Color = annotationColor, // 使用全局配置的颜色
                Rotation = 0,
                OriginalEntity = null // 预览模式没有原始实体
            };

            // 添加到文字信息映射
            _textInfoMap[_previewAnnotationId] = previewTextInfo;

            // 使用镜像变换管理器创建预览视觉对象
            _previewTextVisual = GetMirrorTransformManager().CreateMirrorTextVisual(
                previewTextInfo.Text,
                new System.Windows.Media.SolidColorBrush(previewTextInfo.Color),
                false, // bDoubleSided
                previewTextInfo.Height,
                worldPos,
                previewTextInfo.Rotation,
                "Cascadia Code",
                false,
                previewTextInfo.Rotation  // 传入预览角度作为原始角度
            );

            if (_previewTextVisual != null)
            {
                // 设置Tag以便后续识别
                _previewTextVisual.SetValue(System.Windows.FrameworkElement.TagProperty, _previewAnnotationId);

                // 添加到视图
                this.Children.Add(_previewTextVisual);

                // 设置预览状态
                _isInPreviewMode = true;

                // 立即弹出编辑框
                ShowInlineTextBoxForEdit(_previewTextVisual, mousePos);
            }
        }

        /// <summary>
        /// 清除预览标注
        /// </summary>
        private void ClearPreviewAnnotation()
        {
            if (_isInPreviewMode && _previewTextVisual != null)
            {
                // 从视图中移除
                this.Children.Remove(_previewTextVisual);

                // 从映射中移除
                if (!string.IsNullOrEmpty(_previewAnnotationId))
                {
                    _textInfoMap.Remove(_previewAnnotationId);
                }

                // 重置状态
                _previewTextVisual = null;
                _previewAnnotationId = null;
                _isInPreviewMode = false;
            }
        }

        /// <summary>
        /// 确认预览标注（转换为正式标注并保存到DXF）
        /// </summary>
        /// <param name="finalText">最终的文字内容</param>
        private void ConfirmPreviewAnnotation(string finalText)
        {
            if (!_isInPreviewMode || string.IsNullOrEmpty(_previewAnnotationId))
                return;

            var previewTextInfo = _textInfoMap[_previewAnnotationId];
            if (previewTextInfo == null)
                return;

            // 添加调试信息
            System.Diagnostics.Debug.WriteLine($"=== 确认预览标注调试信息 ===");
            System.Diagnostics.Debug.WriteLine($"当前控件ID: {this.ControlId}");
            System.Diagnostics.Debug.WriteLine($"预览标注ID: {_previewAnnotationId}");
            System.Diagnostics.Debug.WriteLine($"最终文字: {finalText}");
            System.Diagnostics.Debug.WriteLine($"预览标注位置: X={previewTextInfo.Position.X:F2}, Y={previewTextInfo.Position.Y:F2}");
            System.Diagnostics.Debug.WriteLine($"预览标注角度: {previewTextInfo.Rotation:F2}°");

            // 更新文字内容
            previewTextInfo.Text = finalText;
            // 从全局配置中获取印字层颜色，而不是硬编码为青色
            previewTextInfo.Color = GetAnnotationColorFromConfig();

            // 创建正式的标注ID
            var finalAnnotationId = "Text_" + Guid.NewGuid().ToString();

            // 更新预览标注的ID为正式ID
            previewTextInfo.Id = finalAnnotationId;

            // 从预览映射中移除，添加到正式映射
            _textInfoMap.Remove(_previewAnnotationId);
            _textInfoMap[finalAnnotationId] = previewTextInfo;

            // 更新视觉对象
            this.Children.Remove(_previewTextVisual);

            var finalBrush = new System.Windows.Media.SolidColorBrush(previewTextInfo.Color);
            double finalAngle = previewTextInfo.Rotation * Math.PI / 180.0;

            var finalTextVisual = GetTextVisual(
                finalText,
                finalBrush,
                false, // bDoubleSided
                previewTextInfo.Height,
                previewTextInfo.Position,
                        new Vector3D(1, 0, 0),
                        new Vector3D(0, 1, 0),
                previewTextInfo.Rotation
            );

            if (finalTextVisual != null)
            {
                // 设置Tag以便后续识别 - 使用更新后的ID
                finalTextVisual.SetValue(System.Windows.FrameworkElement.TagProperty, finalAnnotationId);

                // 建立视觉对象与文字信息的映射关系
                if (!_annotationModels.ContainsKey("UserAnnotations"))
                {
                    _annotationModels["UserAnnotations"] = new ModelVisual3D();
                    this.Children.Add(_annotationModels["UserAnnotations"]);
                }
                _annotationModels["UserAnnotations"].Children.Add(finalTextVisual);

                // 关键修复：将视觉对象添加到_entityVisualMap中
                _entityVisualMap[finalAnnotationId] = finalTextVisual;
                System.Diagnostics.Debug.WriteLine($"在normal控件中为正式标注创建视觉对象并映射: {finalAnnotationId}");
                System.Diagnostics.Debug.WriteLine($"normal控件_entityVisualMap数量: {_entityVisualMap.Count}");

                // 创建DXF实体并保存
                var textEntity = CreateDxfTextEntity(previewTextInfo);
                if (textEntity != null && _currentDxfDocument != null)
                {
                    // 添加到DXF文档
                    _currentDxfDocument.Entities.Add(textEntity);

                    // 设置原始实体引用
                    previewTextInfo.OriginalEntity = textEntity;

                    // 发布事件通知
                    _eventAggregatorInstance.GetEvent<NewAnnotationCreatedEvent>().Publish(new NewAnnotationCreatedEventArgs
                    {
                        ControlId = this.ControlId,
                        TextInfo = previewTextInfo,
                        DxfEntity = textEntity
                    });

                    // 发布镜像同步事件 - 使用更新后的ID
                    System.Diagnostics.Debug.WriteLine($"准备发布镜像同步事件...");
                    PublishMirrorSyncEvent(MirrorSyncOperation.Add, previewTextInfo, finalAnnotationId);

                    // 确保镜像映射关系正确建立
                    EnsureMirrorMappingEstablished(previewTextInfo);

                    System.Diagnostics.Debug.WriteLine($"新增标注已保存到DXF文档: {finalText} at ({previewTextInfo.Position.X}, {previewTextInfo.Position.Y})");
                }

                // 自动选中新创建的标注
                HandleTextSelection(finalTextVisual);
            }

            // 重置预览状态
            _previewTextVisual = null;
            _previewAnnotationId = null;
            _isInPreviewMode = false;

            System.Diagnostics.Debug.WriteLine($"=== 确认预览标注完成 ===");
        }

        /// <summary>
        /// 显示删除确认对话框
        /// </summary>
        /// <param name="textVisual">要删除的文字视觉对象</param>
        /// <param name="mousePosition">鼠标位置</param>
        private void ShowDeleteConfirmationDialog(ModelVisual3D textVisual, Point mousePosition)
        {
            // 获取文字信息
            string textId = textVisual.GetValue(TagProperty) as string;
            if (string.IsNullOrEmpty(textId) || !_textInfoMap.ContainsKey(textId))
            {
                return;
            }

            var textInfo = _textInfoMap[textId];

            // 创建确认对话框
            var result = System.Windows.MessageBox.Show(
                $"确定要删除标注文字 \"{textInfo.Text}\" 吗？",
                "确认删除",
                System.Windows.MessageBoxButton.YesNo,
                System.Windows.MessageBoxImage.Question);

            if (result == System.Windows.MessageBoxResult.Yes)
            {
                // 用户确认删除
                DeleteTextAnnotation(textVisual, textId);
            }
            else
            {
                // 用户取消删除，清除选中状态
                ClearTextSelection();
            }
        }

        /// <summary>
        /// 删除文字标注
        /// </summary>
        /// <param name="textVisual">文字视觉对象</param>
        /// <param name="textId">文字ID</param>
        private void DeleteTextAnnotation(ModelVisual3D textVisual, string textId)
        {
            if (textVisual == null || string.IsNullOrEmpty(textId) || !_textInfoMap.ContainsKey(textId))
            {
                return;
            }

            var textInfo = _textInfoMap[textId];

            System.Diagnostics.Debug.WriteLine($"=== 开始删除文字标注 ===");
            System.Diagnostics.Debug.WriteLine($"当前控件ID: {this.ControlId}");
            System.Diagnostics.Debug.WriteLine($"要删除的文字ID: {textId}");
            System.Diagnostics.Debug.WriteLine($"要删除的文字内容: {textInfo?.Text ?? "null"}");

            // 从DXF文档中删除实体（如果有的话）
            if (_currentDxfDocument != null && textInfo.OriginalEntity != null)
            {
                _currentDxfDocument.Entities.Remove(textInfo.OriginalEntity);
                System.Diagnostics.Debug.WriteLine($"从DXF文档中删除实体: {textInfo.Text}");
            }

            // 从父容器中移除文字视觉对象
            var parent = VisualTreeHelper.GetParent(textVisual) as ModelVisual3D;
            if (parent != null)
            {
                parent.Children.Remove(textVisual);
                System.Diagnostics.Debug.WriteLine($"从父容器中移除视觉对象");
            }

            // 从文字信息映射中移除
            _textInfoMap.Remove(textId);
            System.Diagnostics.Debug.WriteLine($"从_textInfoMap中移除实体: {textId}");

            // 清除选中状态
            ClearTextSelection();
            System.Diagnostics.Debug.WriteLine($"清除选中状态");

            // 发布删除事件通知
            _eventAggregatorInstance.GetEvent<AnnotationDeletedEvent>().Publish(new AnnotationDeletedEventArgs
            {
                ControlId = this.ControlId,
                TextInfo = textInfo
            });

            // 发布镜像同步事件 - 确保镜像同步正常工作
            System.Diagnostics.Debug.WriteLine($"准备发布镜像同步删除事件，实体ID: {textId}");
            PublishMirrorSyncEvent(MirrorSyncOperation.Delete, null, textId);

            System.Diagnostics.Debug.WriteLine($"=== 删除文字标注完成 ===");
        }

        /// <summary>
        /// 创建DXF文字实体
        /// </summary>
        /// <param name="textInfo">文字信息</param>
        /// <returns>DXF文字实体</returns>
        private netDxf.Entities.Text CreateDxfTextEntity(TextInfo textInfo)
        {
            try
            {
                var textEntity = new netDxf.Entities.Text(
                    textInfo.Text,
                    new netDxf.Vector2(textInfo.Position.X, textInfo.Position.Y),
                    textInfo.Height)
                {
                    Rotation = textInfo.Rotation,
                    Color = netDxf.AciColor.FromTrueColor(System.Drawing.Color.FromArgb(textInfo.Color.A, textInfo.Color.R, textInfo.Color.G, textInfo.Color.B).ToArgb()),
                    Alignment = netDxf.Entities.TextAlignment.BaselineLeft
                };

                return textEntity;
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine($"创建DXF文字实体失败: {ex.Message}");
                return null;
            }
        }

        /// <summary>
        /// 设置当前控件为活动控件
        /// </summary>
        public void SetAsActiveControl()
        {
            // 增加节流机制，避免频繁调用导致问题反复
            var now = DateTime.Now.Ticks / 10000; // 毫秒
            if (_lastActiveControlSetTime > 0 && (now - _lastActiveControlSetTime) < ACTIVE_CONTROL_THROTTLE_MS)
            {
                //TODO: Remove just decrease the debug info
                //System.Diagnostics.Debug.WriteLine($"活跃控件设置节流：距离上次设置 {now - _lastActiveControlSetTime}ms < {ACTIVE_CONTROL_THROTTLE_MS}ms，跳过");
                return;
            }
            _lastActiveControlSetTime = now;

            // 设置当前控件为活跃视口
            this.SetAsActiveViewport(this.ControlId);
            //System.Diagnostics.Debug.WriteLine($"设置活跃视口: {this.ControlId}");
        }

        /// <summary>
        /// 强制设置编辑模式（不依赖事件）
        /// </summary>
        /// <param name="mode">要设置的编辑模式</param>
        public void ForceSetEditingMode(EditingMode mode)
        {
            _currentEditingMode = mode;
            OnEditAnnotationChanged();
        }

        // 新增：防止重复处理的标志位
        private bool _isProcessingClick = false;
        private DateTime _lastClickTime = DateTime.MinValue;
        private const int CLICK_THRESHOLD_MS = 100; // 100毫秒内的点击认为是重复的

        // 新增：防止重复镜像同步处理的集合
        private HashSet<string> _processedMirrorSyncEvents = new HashSet<string>();

        // 新增：跟踪最后处理的移动信息，用于改进重复事件检测
        private Dictionary<string, TextInfo> _lastProcessedMoveInfo = new Dictionary<string, TextInfo>();

        // 相机同步节流控制字段 - 防止问题反复
        private long _lastCameraChangeTime = 0;
        private long _lastActiveControlSetTime = 0;
        private bool _isProcessingCameraSync = false;
        private const int CAMERA_SYNC_THROTTLE_MS = 100; // 相机同步节流时间（毫秒）
        private const int ACTIVE_CONTROL_THROTTLE_MS = 50; // 活跃控件设置节流时间（毫秒）

        // 编辑框可见性管理
        private bool _isEditBoxVisible = true;
        private Point3D _lastEditBoxWorldPosition = new Point3D();
        private bool _editBoxWasHiddenDueToViewport = false;

        #region 镜像同步方法

        /// <summary>
        /// 同步添加实体
        /// </summary>
        /// <param name="textInfo">文字信息</param>
        private void SyncAddEntity(TextInfo textInfo)
        {
            if (textInfo == null) return;

            // --- START: Logic for normal control ---
            if (this.ControlId == "normal")
            {
                try
                {
                    System.Diagnostics.Debug.WriteLine($"=== 开始在normal控件中添加实体 ===");
                    System.Diagnostics.Debug.WriteLine($"原始实体ID: {textInfo.Id}");
                    System.Diagnostics.Debug.WriteLine($"原始文字: {textInfo.Text}");
                    System.Diagnostics.Debug.WriteLine($"原始位置: X={textInfo.Position.X:F2}, Y={textInfo.Position.Y:F2}");
                    System.Diagnostics.Debug.WriteLine($"原始角度: {textInfo.Rotation:F2}°");

                    // Check if the entity already exists in this control's maps
                    if (_textInfoMap.ContainsKey(textInfo.Id))
                    {
                        System.Diagnostics.Debug.WriteLine($"实体 {textInfo.Id} 已在normal控件中存在，跳过添加。");
                        return;
                    }

                    // Create visual object for the original entity
                    var originalTextVisual = GetMirrorTransformManager().CreateMirrorTextVisual(
                        textInfo.Text,
                        new SolidColorBrush(textInfo.Color),
                        true,
                        textInfo.Height,
                        textInfo.Position,
                        textInfo.Rotation,
                        "Cascadia Code",
                        textInfo.Underline,
                        textInfo.Rotation
                    );

                    if (originalTextVisual == null)
                    {
                        System.Diagnostics.Debug.WriteLine($"错误: 在normal控件中创建原始视觉对象失败");
                        return;
                    }

                    originalTextVisual.SetValue(FrameworkElement.TagProperty, textInfo.Id);

                    // Ensure layer container exists
                    var layerName = textInfo.LayerName ?? "Default";
                    if (!_annotationModels.ContainsKey(layerName))
                    {
                        var newLayer = new ModelVisual3D();
                        _annotationModels[layerName] = newLayer;
                        this.Children.Add(newLayer);
                        System.Diagnostics.Debug.WriteLine($"在normal控件中创建新的图层容器: {layerName}");
                    }

                    var originalLayerContainer = _annotationModels[layerName];
                    if (originalLayerContainer != null)
                    {
                        originalLayerContainer.Children.Add(originalTextVisual);
                        _entityVisualMap[textInfo.Id] = originalTextVisual; // CRUCIAL: Map original ID to its visual
                        _textInfoMap[textInfo.Id] = textInfo; // CRUCIAL: Add TextInfo to local map
                        System.Diagnostics.Debug.WriteLine($"在normal控件中为原始实体创建视觉对象并映射: {textInfo.Id}");
                        System.Diagnostics.Debug.WriteLine($"normal控件_entityVisualMap数量: {_entityVisualMap.Count}");
                        System.Diagnostics.Debug.WriteLine($"normal控件_textInfoMap数量: {_textInfoMap.Count}");
                    }
                    else
                    {
                        System.Diagnostics.Debug.WriteLine($"错误: normal控件的图层容器为空: {layerName}");
                    }

                    this.InvalidateVisual();
                    System.Diagnostics.Debug.WriteLine($"=== 在normal控件中添加实体完成 ===");
                }
                catch (Exception ex)
                {
                    System.Diagnostics.Debug.WriteLine($"在normal控件中添加实体失败: {ex.Message}");
                    System.Diagnostics.Debug.WriteLine($"异常堆栈: {ex.StackTrace}");
                }
                return; // Exit after handling normal control logic
            }
            // --- END: Logic for normal control ---

            // --- START: Logic for mirror control ---
            try
            {
                System.Diagnostics.Debug.WriteLine($"=== 开始在mirror控件中添加实体 (镜像同步) ===");
                System.Diagnostics.Debug.WriteLine($"原始实体ID: {textInfo.Id}");
                System.Diagnostics.Debug.WriteLine($"原始文字: {textInfo.Text}");
                System.Diagnostics.Debug.WriteLine($"原始位置: X={textInfo.Position.X:F2}, Y={textInfo.Position.Y:F2}");
                System.Diagnostics.Debug.WriteLine($"原始角度: {textInfo.Rotation:F2}°");
                System.Diagnostics.Debug.WriteLine($"当前控件ID: {this.ControlId}");

                // 镜像实体重复检查：检查是否已经存在镜像实体（防止重复添加）
                string existingMirroredId = GetMirroredEntityId(textInfo.Id);
                if (!string.IsNullOrEmpty(existingMirroredId) && _textInfoMap.ContainsKey(existingMirroredId))
                {
                    System.Diagnostics.Debug.WriteLine($"镜像实体已存在，跳过添加: {existingMirroredId}");
                    return;
                }

                // 创建镜像位置的文字信息
                var mirroredTextInfo = CreateMirroredTextInfo(textInfo);
                if (mirroredTextInfo == null)
                {
                    System.Diagnostics.Debug.WriteLine($"镜像同步添加实体失败: 无法创建镜像文字信息");
                    return;
                }

                // 检查是否已存在相同的镜像实体（防止重复添加）
                if (_textInfoMap.ContainsKey(mirroredTextInfo.Id))
                {
                    System.Diagnostics.Debug.WriteLine($"镜像同步添加实体失败: 镜像实体已存在 {mirroredTextInfo.Id}");
                    return;
                }

                // 添加到当前控件的_textInfoMap
                _textInfoMap.Add(mirroredTextInfo.Id, mirroredTextInfo);
                System.Diagnostics.Debug.WriteLine($"镜像实体已添加到_textInfoMap: {mirroredTextInfo.Id}");

                // 使用镜像变换管理器创建视觉对象
                var textVisual = GetMirrorTransformManager().CreateMirrorTextVisual(
                    mirroredTextInfo.Text,
                    new SolidColorBrush(mirroredTextInfo.Color),
                    true,
                    mirroredTextInfo.Height,
                    mirroredTextInfo.Position,
                    mirroredTextInfo.Rotation,
                    "Cascadia Code",
                    mirroredTextInfo.Underline,
                    mirroredTextInfo.Rotation
                );

                if (textVisual == null)
                {
                    System.Diagnostics.Debug.WriteLine($"错误: 镜像视觉对象创建失败");
                    return;
                }

                System.Diagnostics.Debug.WriteLine($"镜像视觉对象创建成功，Tag设置为: {mirroredTextInfo.Id}");
                textVisual.SetValue(FrameworkElement.TagProperty, mirroredTextInfo.Id);

                // 添加到图层容器
                var layerNameMirror = mirroredTextInfo.LayerName ?? "Default";
                if (!_annotationModels.ContainsKey(layerNameMirror))
                {
                    var newLayer = new ModelVisual3D();
                    _annotationModels[layerNameMirror] = newLayer;
                    this.Children.Add(newLayer);
                    System.Diagnostics.Debug.WriteLine($"创建新的图层容器: {layerNameMirror}");
                }

                var layerContainer = _annotationModels[layerNameMirror];
                if (layerContainer != null)
                {
                    layerContainer.Children.Add(textVisual);
                    System.Diagnostics.Debug.WriteLine($"镜像视觉对象已添加到图层容器: {layerNameMirror}");
                    System.Diagnostics.Debug.WriteLine($"图层容器Children数量: {layerContainer.Children.Count}");
                }
                else
                {
                    System.Diagnostics.Debug.WriteLine($"错误: 图层容器为空: {layerNameMirror}");
                    return;
                }

                // 更新实体视觉映射表 - 只映射镜像实体ID
                _entityVisualMap[mirroredTextInfo.Id] = textVisual;
                System.Diagnostics.Debug.WriteLine($"镜像实体已添加到_entityVisualMap: {mirroredTextInfo.Id}");

                // 更新边界
                UpdateBoundariesForMirroredEntity(mirroredTextInfo);

                // 建立原始实体ID和镜像实体ID的本地映射关系 (for PREVIEW entities)
                if (!_handleMapping.ContainsKey(textInfo.Id))
                {
                    _handleMapping[textInfo.Id] = mirroredTextInfo.Id;
                    System.Diagnostics.Debug.WriteLine($"建立Handle映射: {textInfo.Id} -> {mirroredTextInfo.Id}");
                }
                if (!_reverseHandleMapping.ContainsKey(mirroredTextInfo.Id))
                {
                    _reverseHandleMapping[mirroredTextInfo.Id] = textInfo.Id;
                    System.Diagnostics.Debug.WriteLine($"建立反向Handle映射: {mirroredTextInfo.Id} -> {textInfo.Id}");
                }

                this.InvalidateVisual();

                if (layerContainer != null)
                {
                    System.Diagnostics.Debug.WriteLine($"镜像实体在图层容器中存在: {layerContainer.Children.Contains(textVisual)}");
                }
                else
                {
                    System.Diagnostics.Debug.WriteLine($"警告: 图层容器为空，无法检查镜像实体存在性");
                }

                System.Diagnostics.Debug.WriteLine($"=== 镜像同步添加实体完成 ===");
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine($"镜像同步添加实体失败: {ex.Message}");
                System.Diagnostics.Debug.WriteLine($"异常堆栈: {ex.StackTrace}");
            }
            // --- END: Logic for mirror control ---
        }



        /// <summary>
        /// 编辑模式下的相机同步优化
        /// </summary>
        /// <param name="controlId">控件ID</param>
        private void OptimizeCameraSyncForEditing(string controlId)
        {
            try
            {
                if (string.IsNullOrEmpty(controlId)) return;

                System.Diagnostics.Debug.WriteLine($"=== 开始编辑模式相机同步优化 ===");
                System.Diagnostics.Debug.WriteLine($"控件ID: {controlId}");
                System.Diagnostics.Debug.WriteLine($"当前编辑模式: {_currentEditingMode}");

                // 在编辑模式下，确保相机同步的实时性和准确性
                if (_currentEditingMode != EditingMode.None)
                {
                    // 优先同步缩放，确保视图一致性
                    this.SyncCameraZoom(controlId);

                    // 短暂延迟后同步其他属性，避免冲突
                    System.Windows.Threading.Dispatcher.CurrentDispatcher.BeginInvoke(
                        System.Windows.Threading.DispatcherPriority.Background,
                        new Action(() =>
                        {
                            try
                            {
                                // 同步相机位置和方向
                                this.SyncCameraPosition(controlId);
                                this.SyncCameraDirection(controlId);

                                System.Diagnostics.Debug.WriteLine($"编辑模式相机同步优化完成: {controlId}");
                            }
                            catch (Exception ex)
                            {
                                System.Diagnostics.Debug.WriteLine($"编辑模式相机同步优化异常: {ex.Message}");
                            }
                        }));
                }

                System.Diagnostics.Debug.WriteLine($"=== 编辑模式相机同步优化完成 ===");
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine($"编辑模式相机同步优化失败: {ex.Message}");
            }
        }

        /// <summary>
        /// 同步相机视图（可选功能，优先级较低）
        /// </summary>
        /// <param name="sourceControlId">源控件ID</param>
        private void SyncCameraViewIfNeeded(string sourceControlId)
        {
            try
            {
                // 这里可以实现相机视图的同步
                // 例如：同步缩放级别、平移位置等
                // 由于这是可选功能，优先级较低，暂时只记录日志
                System.Diagnostics.Debug.WriteLine($"相机视图同步请求来自: {sourceControlId}");

                if (this.Camera != null)
                {
                    System.Diagnostics.Debug.WriteLine($"当前相机位置: {this.Camera.Position}");

                    // 检查相机类型并获取相应属性
                    if (this.Camera is System.Windows.Media.Media3D.PerspectiveCamera perspectiveCamera)
                    {
                        System.Diagnostics.Debug.WriteLine($"当前相机目标: {perspectiveCamera.LookDirection}");
                        System.Diagnostics.Debug.WriteLine($"当前相机向上方向: {perspectiveCamera.UpDirection}");
                    }
                    else if (this.Camera is System.Windows.Media.Media3D.OrthographicCamera orthographicCamera)
                    {
                        System.Diagnostics.Debug.WriteLine($"当前相机目标: {orthographicCamera.LookDirection}");
                        System.Diagnostics.Debug.WriteLine($"当前相机向上方向: {orthographicCamera.UpDirection}");
                    }
                    else
                    {
                        System.Diagnostics.Debug.WriteLine($"当前相机类型: {this.Camera.GetType().Name}");
                        System.Diagnostics.Debug.WriteLine($"当前相机向上方向: {this.Camera.UpDirection}");
                    }
                }
                else
                {
                    System.Diagnostics.Debug.WriteLine($"相机未初始化");
                }
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine($"相机视图同步失败: {ex.Message}");
            }
        }

        /// <summary>
        /// 确保镜像映射关系正确建立
        /// </summary>
        /// <param name="textInfo">文字信息</param>
        private void EnsureMirrorMappingEstablished(TextInfo textInfo)
        {
            if (textInfo == null) return;

            try
            {
                System.Diagnostics.Debug.WriteLine($"=== 确保镜像映射关系建立 ===");
                System.Diagnostics.Debug.WriteLine($"实体ID: {textInfo.Id}");
                System.Diagnostics.Debug.WriteLine($"当前控件ID: {this.ControlId}");

                // 检查是否已经建立了映射关系
                if (_handleMapping.ContainsKey(textInfo.Id) || _reverseHandleMapping.ContainsKey(textInfo.Id))
                {
                    System.Diagnostics.Debug.WriteLine($"镜像映射关系已存在，跳过建立");
                    return;
                }

                // 生成镜像实体ID
                string mirroredEntityId = GenerateMirroredEntityId(textInfo.Id);
                System.Diagnostics.Debug.WriteLine($"生成镜像实体ID: {mirroredEntityId}");

                // 建立映射关系
                _handleMapping[textInfo.Id] = mirroredEntityId;
                _reverseHandleMapping[mirroredEntityId] = textInfo.Id;

                System.Diagnostics.Debug.WriteLine($"镜像映射关系已建立: {textInfo.Id} <-> {mirroredEntityId}");
                System.Diagnostics.Debug.WriteLine($"=== 镜像映射关系建立完成 ===");
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine($"确保镜像映射关系建立失败: {ex.Message}");
                System.Diagnostics.Debug.WriteLine($"异常堆栈: {ex.StackTrace}");
            }
        }

        /// <summary>
        /// 更新镜像实体的边界
        /// </summary>
        /// <param name="mirroredTextInfo">镜像文字信息</param>
        private void UpdateBoundariesForMirroredEntity(TextInfo mirroredTextInfo)
        {
            try
            {
                if (mirroredTextInfo == null || mirroredTextInfo.Position == null) return;

                System.Diagnostics.Debug.WriteLine($"=== 开始更新镜像实体边界 ===");
                System.Diagnostics.Debug.WriteLine($"镜像实体ID: {mirroredTextInfo.Id}");
                System.Diagnostics.Debug.WriteLine($"镜像实体位置: {mirroredTextInfo.Position}");
                System.Diagnostics.Debug.WriteLine($"镜像实体旋转角度: {mirroredTextInfo.Rotation}°");

                var position = mirroredTextInfo.Position;
                var height = mirroredTextInfo.Height;

                // 使用更准确的文字尺寸计算
                var textSize = MeasureText(mirroredTextInfo.Text, height, "Cascadia Code");
                double halfHeight = height / 2.0;
                double halfWidth = textSize.Width / 2.0;

                System.Diagnostics.Debug.WriteLine($"文字尺寸: {textSize.Width} x {textSize.Height}");
                System.Diagnostics.Debug.WriteLine($"半宽半高: {halfWidth:F2} x {halfHeight:F2}");

                // 考虑旋转角度的影响（转换为弧度）
                double angleRad = mirroredTextInfo.Rotation * Math.PI / 180.0;
                double cos = Math.Cos(angleRad);
                double sin = Math.Sin(angleRad);

                System.Diagnostics.Debug.WriteLine($"旋转角度(弧度): {angleRad:F4}, cos: {cos:F4}, sin: {sin:F4}");

                // 计算旋转后的四个角点
                var corners = new[]
                {
                    new Point3D(-halfWidth, -halfHeight, 0),
                    new Point3D(halfWidth, -halfHeight, 0),
                    new Point3D(halfWidth, halfHeight, 0),
                    new Point3D(-halfWidth, halfHeight, 0)
                };

                // 记录原始边界值
                var oldMinX = _minX;
                var oldMaxX = _maxX;
                var oldMinY = _minY;
                var oldMaxY = _maxY;

                // 应用旋转和平移
                for (int i = 0; i < corners.Length; i++)
                {
                    var corner = corners[i];
                    double rotatedX = corner.X * cos - corner.Y * sin;
                    double rotatedY = corner.X * sin + corner.Y * cos;

                    var worldCorner = new Point3D(
                        position.X + rotatedX,
                        position.Y + rotatedY,
                        position.Z
                    );

                    System.Diagnostics.Debug.WriteLine($"角点{i}: 原始({corner.X:F2}, {corner.Y:F2}) -> 旋转({rotatedX:F2}, {rotatedY:F2}) -> 世界({worldCorner.X:F2}, {worldCorner.Y:F2})");

                    // 更新边界
                    _minX = Math.Min(_minX, worldCorner.X);
                    _minY = Math.Min(_minY, worldCorner.Y);
                    _maxX = Math.Max(_maxX, worldCorner.X);
                    _maxY = Math.Max(_maxY, worldCorner.Y);
                }

                System.Diagnostics.Debug.WriteLine($"边界更新: X[{oldMinX:F2}, {oldMaxX:F2}] -> [{_minX:F2}, {_maxX:F2}]");
                System.Diagnostics.Debug.WriteLine($"边界更新: Y[{oldMinY:F2}, {oldMaxY:F2}] -> [{_minY:F2}, {_maxY:F2}]");
                System.Diagnostics.Debug.WriteLine($"=== 镜像实体边界更新完成 ===");
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine($"更新镜像实体边界失败: {ex.Message}");
                System.Diagnostics.Debug.WriteLine($"异常堆栈: {ex.StackTrace}");
            }
        }

        /// <summary>
        /// 同步编辑实体
        /// </summary>
        /// <param name="textInfo">文字信息</param>
        private void SyncEditEntity(TextInfo textInfo)
        {
            if (textInfo == null) return;

            try
            {
                System.Diagnostics.Debug.WriteLine($"=== 开始镜像同步编辑实体 ===");
                System.Diagnostics.Debug.WriteLine($"原始实体ID: {textInfo.Id}");
                System.Diagnostics.Debug.WriteLine($"原始文字: {textInfo.Text}");
                System.Diagnostics.Debug.WriteLine($"原始位置: X={textInfo.Position.X:F2}, Y={textInfo.Position.Y:F2}");
                System.Diagnostics.Debug.WriteLine($"原始角度: {textInfo.Rotation:F2}°");
                System.Diagnostics.Debug.WriteLine($"当前控件ID: {this.ControlId}");

                // 查找镜像实体ID - 支持双向查找
                string mirroredEntityId = GetMirroredEntityId(textInfo.Id);
                if (string.IsNullOrEmpty(mirroredEntityId))
                {
                    // 如果找不到镜像ID，尝试反向查找（当前实体可能是镜像实体）
                    mirroredEntityId = GetOriginalEntityId(textInfo.Id);
                    if (!string.IsNullOrEmpty(mirroredEntityId))
                    {
                        // 当前实体是镜像实体，需要更新原始实体
                        var originalEntityId = mirroredEntityId;
                        mirroredEntityId = textInfo.Id; // 当前实体ID就是镜像实体ID
                        System.Diagnostics.Debug.WriteLine($"反向查找成功: 当前实体 {textInfo.Id} 是镜像实体，原始实体ID: {originalEntityId}");
                    }
                    else
                    {
                        // 尝试通过全局镜像映射管理器查找
                        System.Diagnostics.Debug.WriteLine($"本地映射查找失败，尝试通过全局镜像映射管理器查找");
                        string documentName = _currentDxfDocument?.Name;
                        if (!string.IsNullOrEmpty(documentName))
                        {
                            string originalDocumentName = GetOriginalDocumentName(documentName);
                            if (!string.IsNullOrEmpty(originalDocumentName))
                            {
                                // 尝试通过全局映射管理器查找
                                var mirroredHandle = MirrorEntityMappingManager.GetMirroredHandle(originalDocumentName, textInfo.Id);
                                if (!string.IsNullOrEmpty(mirroredHandle))
                                {
                                    mirroredEntityId = mirroredHandle;
                                    System.Diagnostics.Debug.WriteLine($"通过全局映射管理器找到镜像实体ID: {textInfo.Id} -> {mirroredEntityId}");
                                }
                                else
                                {
                                    // 尝试反向查找
                                    var originalHandle = MirrorEntityMappingManager.GetOriginalHandle(originalDocumentName, textInfo.Id);
                                    if (!string.IsNullOrEmpty(originalHandle))
                                    {
                                        mirroredEntityId = textInfo.Id; // 当前实体就是镜像实体
                                        System.Diagnostics.Debug.WriteLine($"通过全局映射管理器反向查找成功: 当前实体 {textInfo.Id} 是镜像实体，原始实体ID: {originalHandle}");
                                    }
                                }
                            }
                        }

                        if (string.IsNullOrEmpty(mirroredEntityId))
                        {
                            System.Diagnostics.Debug.WriteLine($"镜像同步编辑实体失败: 无法获取镜像实体ID");
                            return;
                        }
                    }
                }

                System.Diagnostics.Debug.WriteLine($"查找镜像实体ID: {textInfo.Id} -> {mirroredEntityId}");

                if (_textInfoMap.ContainsKey(mirroredEntityId))
                {
                    var localTextInfo = _textInfoMap[mirroredEntityId];
                    System.Diagnostics.Debug.WriteLine($"找到镜像实体: {mirroredEntityId}");
                    System.Diagnostics.Debug.WriteLine($"镜像实体当前文字: {localTextInfo.Text}");
                    System.Diagnostics.Debug.WriteLine($"镜像实体当前位置: X={localTextInfo.Position.X:F2}, Y={localTextInfo.Position.Y:F2}");

                    // 更新实体的属性
                    localTextInfo.Text = textInfo.Text;
                    localTextInfo.Color = textInfo.Color;
                    localTextInfo.Height = textInfo.Height;
                    localTextInfo.Underline = textInfo.Underline;
                    localTextInfo.Rotation = textInfo.Rotation;
                    localTextInfo.Position = textInfo.Position;

                    // 关键修复：确保镜像实体有正确的OriginalEntity属性
                    if (localTextInfo.OriginalEntity == null && textInfo.OriginalEntity != null)
                    {
                        localTextInfo.OriginalEntity = textInfo.OriginalEntity;
                        System.Diagnostics.Debug.WriteLine($"为镜像实体设置OriginalEntity: {textInfo.OriginalEntity.GetType().Name}");
                    }

                    System.Diagnostics.Debug.WriteLine($"镜像实体属性已更新:");
                    System.Diagnostics.Debug.WriteLine($"  新文字: {localTextInfo.Text}");
                    System.Diagnostics.Debug.WriteLine($"  新颜色: {localTextInfo.Color}");
                    System.Diagnostics.Debug.WriteLine($"  新高度: {localTextInfo.Height}");
                    System.Diagnostics.Debug.WriteLine($"  新下划线: {localTextInfo.Underline}");
                    System.Diagnostics.Debug.WriteLine($"  新角度: {localTextInfo.Rotation:F2}°");
                    System.Diagnostics.Debug.WriteLine($"  新位置: X={localTextInfo.Position.X:F2}, Y={localTextInfo.Position.Y:F2}");
                    System.Diagnostics.Debug.WriteLine($"  OriginalEntity: {localTextInfo.OriginalEntity?.GetType().Name ?? "null"}");

                    // 更新视觉对象 - 使用改进的更新方法
                    UpdateTextVisual(localTextInfo);
                    System.Diagnostics.Debug.WriteLine($"镜像实体视觉对象已更新");

                    // 同时更新原始实体的视觉对象（如果存在）
                    if (_handleMapping.ContainsKey(textInfo.Id))
                    {
                        var originalEntityId = textInfo.Id;
                        var originalMirroredEntityId = _handleMapping[textInfo.Id];

                        // 创建原始实体的TextInfo用于更新
                        var originalTextInfo = new TextInfo
                        {
                            Id = originalEntityId,
                            Text = textInfo.Text,
                            Position = textInfo.Position,
                            Rotation = textInfo.Rotation,
                            Height = textInfo.Height,
                            Color = textInfo.Color,
                            Underline = textInfo.Underline,
                            LayerName = textInfo.LayerName,
                            OriginalEntity = textInfo.OriginalEntity
                        };

                        // 更新原始实体的视觉对象
                        UpdateTextVisual(originalTextInfo);
                        System.Diagnostics.Debug.WriteLine($"原始实体视觉对象已更新: {originalEntityId}");
                    }

                    // 注意：在mirror控件中，镜像实体的视觉对象已经在上面通过UpdateTextVisual(localTextInfo)更新了
                    // 不需要重复更新，避免破坏映射关系
                    if (this.ControlId == "mirror")
                    {
                        System.Diagnostics.Debug.WriteLine($"在mirror控件中，镜像实体视觉对象已通过localTextInfo更新，跳过重复更新");
                    }

                    // 检查更新后的状态
                    if (_entityVisualMap.ContainsKey(mirroredEntityId))
                    {
                        var visual = _entityVisualMap[mirroredEntityId];
                        System.Diagnostics.Debug.WriteLine($"镜像实体视觉对象存在: {visual != null}");
                        System.Diagnostics.Debug.WriteLine($"视觉对象Tag: {visual.GetValue(FrameworkElement.TagProperty)}");
                    }

                    System.Diagnostics.Debug.WriteLine($"镜像同步编辑实体成功: {textInfo.Id} -> {mirroredEntityId}");

                    //// 调整相机视图以显示编辑后的实体
                    //AdjustCameraView();

                    // 强制刷新UI
                    this.InvalidateVisual();
                }
                else
                {
                    System.Diagnostics.Debug.WriteLine($"镜像同步编辑实体失败: 未找到镜像实体 {textInfo.Id} -> {mirroredEntityId}");
                    System.Diagnostics.Debug.WriteLine($"当前_textInfoMap中的实体数量: {_textInfoMap.Count}");
                    System.Diagnostics.Debug.WriteLine($"当前_entityVisualMap中的实体数量: {_entityVisualMap.Count}");

                    // 尝试通过其他方式查找
                    foreach (var kvp in _textInfoMap)
                    {
                        if (kvp.Value.Text == textInfo.Text)
                        {
                            System.Diagnostics.Debug.WriteLine($"找到相同文字的实体: {kvp.Key} -> {kvp.Value.Text}");
                        }
                    }
                }

                System.Diagnostics.Debug.WriteLine($"=== 镜像同步编辑实体完成 ===");
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine($"镜像同步编辑实体失败: {ex.Message}");
                System.Diagnostics.Debug.WriteLine($"异常堆栈: {ex.StackTrace}");
            }
        }

        /// <summary>
        /// 同步删除实体
        /// </summary>
        /// <param name="entityId">实体ID</param>
        private void SyncDeleteEntity(string entityId)
        {
            if (string.IsNullOrEmpty(entityId)) return;

            System.Diagnostics.Debug.WriteLine($"=== 开始同步删除实体 ===");
            System.Diagnostics.Debug.WriteLine($"当前控件ID: {this.ControlId}");
            System.Diagnostics.Debug.WriteLine($"要删除的实体ID: {entityId}");
            System.Diagnostics.Debug.WriteLine($"当前_textInfoMap中的实体数量: {_textInfoMap.Count}");
            System.Diagnostics.Debug.WriteLine($"当前_entityVisualMap中的实体数量: {_entityVisualMap.Count}");

            try
            {
                // 关键修复：根据删除方向确定要删除的实体
                string entityIdToDelete = DetermineEntityToDelete(entityId);

                if (entityIdToDelete != null && _textInfoMap.ContainsKey(entityIdToDelete))
                {
                    var textInfo = _textInfoMap[entityIdToDelete];
                    System.Diagnostics.Debug.WriteLine($"找到要删除的实体: {entityIdToDelete}, 文字内容: {textInfo?.Text}");

                    // 从场景中移除视觉对象
                    if (_entityVisualMap.ContainsKey(entityIdToDelete))
                    {
                        var visualModel = _entityVisualMap[entityIdToDelete];

                        // 从正确的父容器中移除视觉对象
                        bool removed = false;
                        foreach (var layerModel in _annotationModels.Values)
                        {
                            if (layerModel.Children.Contains(visualModel))
                            {
                                layerModel.Children.Remove(visualModel);
                                removed = true;
                                System.Diagnostics.Debug.WriteLine($"从图层中移除视觉对象: {entityIdToDelete}");
                                break;
                            }
                        }

                        if (!removed)
                        {
                            System.Diagnostics.Debug.WriteLine($"警告: 未找到视觉对象的父容器: {entityIdToDelete}");
                        }

                        // 从实体视觉映射表中移除
                        _entityVisualMap.Remove(entityIdToDelete);
                        System.Diagnostics.Debug.WriteLine($"从_entityVisualMap中移除: {entityIdToDelete}");
                    }
                    else
                    {
                        System.Diagnostics.Debug.WriteLine($"警告: 未找到视觉对象: {entityIdToDelete}");
                    }

                    // 从映射中移除
                    _textInfoMap.Remove(entityIdToDelete);
                    System.Diagnostics.Debug.WriteLine($"从_textInfoMap中移除: {entityIdToDelete}");

                    // 清除选中状态（如果当前选中的是要删除的实体）
                    if (_selectedTextId == entityIdToDelete)
                    {
                        ClearTextSelection();
                        System.Diagnostics.Debug.WriteLine($"清除选中状态: {entityIdToDelete}");
                    }

                    System.Diagnostics.Debug.WriteLine($"镜像同步删除实体成功: {entityId} -> {entityIdToDelete}");
                }
                else
                {
                    System.Diagnostics.Debug.WriteLine($"镜像同步删除实体失败: 未找到实体 {entityId} 或其镜像实体");
                    
                    // 添加调试信息：显示当前所有可用的实体ID
                    System.Diagnostics.Debug.WriteLine($"当前_textInfoMap中的所有实体ID:");
                    foreach (var kvp in _textInfoMap)
                    {
                        System.Diagnostics.Debug.WriteLine($"  - {kvp.Key}: {kvp.Value?.Text ?? "null"}");
                    }
                    
                    System.Diagnostics.Debug.WriteLine($"当前_entityVisualMap中的所有实体ID:");
                    foreach (var kvp in _entityVisualMap)
                    {
                        System.Diagnostics.Debug.WriteLine($"  - {kvp.Key}");
                    }
                }
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine($"同步删除实体失败: {ex.Message}");
                System.Diagnostics.Debug.WriteLine($"异常堆栈: {ex.StackTrace}");
            }
        }

        /// <summary>
        /// 提取实体的原始句柄（移除前缀）
        /// </summary>
        /// <param name="entityId">实体ID</param>
        /// <returns>原始句柄，如果无法提取则返回原ID</returns>
        private string ExtractRawHandle(string entityId)
        {
            if (string.IsNullOrEmpty(entityId))
                return entityId;

            // 支持的前缀列表
            string[] prefixes = { "Text_", "MText_", "Line_", "Circle_", "Arc_", "Ellipse_", "Polyline_" };
            
            foreach (string prefix in prefixes)
            {
                if (entityId.StartsWith(prefix))
                {
                    return entityId.Substring(prefix.Length);
                }
            }
            
            return entityId;
        }

        /// <summary>
        /// 根据删除方向确定要删除的实体（简化版本：只考虑normal到mirror的映射）
        /// </summary>
        /// <param name="entityId">要删除的实体ID</param>
        /// <returns>实际应该删除的实体ID</returns>
        private string DetermineEntityToDelete(string entityId)
        {
            System.Diagnostics.Debug.WriteLine($"=== 确定要删除的实体 ===");
            System.Diagnostics.Debug.WriteLine($"当前控件ID: {this.ControlId}");
            System.Diagnostics.Debug.WriteLine($"要删除的实体ID: {entityId}");

            // 简化策略：只考虑normal到mirror的映射关系
            if (this.ControlId == "normal")
            {
                // Normal视图：直接删除传入的实体ID
                if (_textInfoMap.ContainsKey(entityId))
                {
                    System.Diagnostics.Debug.WriteLine($"Normal视图直接匹配成功: {entityId}");
                    return entityId;
                }
            }
            else if (this.ControlId == "mirror")
            {
                // Mirror视图：通过映射关系找到对应的镜像实体
                System.Diagnostics.Debug.WriteLine($"Mirror视图，查找对应的镜像实体: {entityId}");

                // 策略1：通过本地映射查找镜像实体
                if (_handleMapping.ContainsKey(entityId))
                {
                    string mirroredId = _handleMapping[entityId];
                    System.Diagnostics.Debug.WriteLine($"本地映射找到镜像实体ID: {entityId} -> {mirroredId}");
                    if (_textInfoMap.ContainsKey(mirroredId))
                    {
                        System.Diagnostics.Debug.WriteLine($"镜像实体在当前视图中存在: {mirroredId}");
                        return mirroredId;
                    }
                }

                // 策略2：通过rawHandle查找镜像实体
                string rawHandle = ExtractRawHandle(entityId);
                if (!string.IsNullOrEmpty(rawHandle) && rawHandle != entityId && _handleMapping.ContainsKey(rawHandle))
                {
                    string mirroredId = _handleMapping[rawHandle];
                    System.Diagnostics.Debug.WriteLine($"通过rawHandle本地映射找到镜像实体ID: {rawHandle} -> {mirroredId}");
                    if (_textInfoMap.ContainsKey(mirroredId))
                    {
                        System.Diagnostics.Debug.WriteLine($"镜像实体在当前视图中存在: {mirroredId}");
                        return mirroredId;
                    }
                }

                // 策略3：通过全局映射管理器查找镜像实体
                string originalDocumentName = GetOriginalDocumentName(_currentDxfDocument?.Name);
                if (!string.IsNullOrEmpty(originalDocumentName))
                {
                    // 尝试使用原始ID查找镜像实体
                    var mirroredHandle = MirrorEntityMappingManager.GetMirroredHandle(originalDocumentName, entityId);
                    if (!string.IsNullOrEmpty(mirroredHandle))
                    {
                        System.Diagnostics.Debug.WriteLine($"全局映射找到镜像实体ID: {entityId} -> {mirroredHandle}");
                        if (_textInfoMap.ContainsKey(mirroredHandle))
                        {
                            System.Diagnostics.Debug.WriteLine($"镜像实体在当前视图中存在: {mirroredHandle}");
                            return mirroredHandle;
                        }
                    }

                    // 尝试使用rawHandle查找镜像实体
                    if (!string.IsNullOrEmpty(rawHandle))
                    {
                        var mirroredHandleByRaw = MirrorEntityMappingManager.GetMirroredHandle(originalDocumentName, rawHandle);
                        if (!string.IsNullOrEmpty(mirroredHandleByRaw))
                        {
                            System.Diagnostics.Debug.WriteLine($"通过rawHandle全局映射找到镜像实体ID: {rawHandle} -> {mirroredHandleByRaw}");
                            if (_textInfoMap.ContainsKey(mirroredHandleByRaw))
                            {
                                System.Diagnostics.Debug.WriteLine($"镜像实体在当前视图中存在: {mirroredHandleByRaw}");
                                return mirroredHandleByRaw;
                            }
                        }
                    }
                }

                // 策略4：如果以上都失败，检查是否传入的entityId本身就是镜像实体ID
                // 这种情况可能发生在某些特殊情况下
                if (_textInfoMap.ContainsKey(entityId))
                {
                    System.Diagnostics.Debug.WriteLine($"传入的entityId本身就是镜像实体ID: {entityId}");
                    return entityId;
                }
            }

            System.Diagnostics.Debug.WriteLine($"无法确定要删除的实体");
            return null;
        }


        /// <summary>
        /// 创建镜像文字信息
        /// </summary>
        /// <param name="originalTextInfo">原始文字信息</param>
        /// <returns>镜像文字信息</returns>
        private TextInfo CreateMirroredTextInfo(TextInfo originalTextInfo)
        {
            if (originalTextInfo == null)
            {
                System.Diagnostics.Debug.WriteLine($"错误: CreateMirroredTextInfo 接收到空的 originalTextInfo");
                return null;
            }

            try
            {
                System.Diagnostics.Debug.WriteLine($"=== 开始创建镜像文字信息 ===");
                System.Diagnostics.Debug.WriteLine($"原始实体ID: {originalTextInfo.Id}");
                System.Diagnostics.Debug.WriteLine($"原始文字: {originalTextInfo.Text}");
                System.Diagnostics.Debug.WriteLine($"原始位置: X={originalTextInfo.Position.X:F2}, Y={originalTextInfo.Position.Y:F2}, Z={originalTextInfo.Position.Z:F2}");
                System.Diagnostics.Debug.WriteLine($"原始角度: {originalTextInfo.Rotation:F2}°");
                System.Diagnostics.Debug.WriteLine($"当前控件ID: {this.ControlId}");

                // 生成唯一的镜像实体ID，避免与原始实体ID冲突
                string mirroredId = GenerateMirroredEntityId(originalTextInfo.Id);
                System.Diagnostics.Debug.WriteLine($"生成的镜像ID: {mirroredId}");

                var mirroredTextInfo = new TextInfo
                {
                    Id = mirroredId, // 使用唯一的镜像ID
                    Text = originalTextInfo.Text ?? string.Empty,
                    Color = originalTextInfo.Color,
                    Height = Math.Max(0.1, originalTextInfo.Height), // 确保高度为正数
                    Underline = originalTextInfo.Underline,
                    LayerName = originalTextInfo.LayerName ?? "Default",
                    OriginalEntity = originalTextInfo.OriginalEntity,
                    Position = originalTextInfo.Position,
                    Rotation = originalTextInfo.Rotation
                };

                System.Diagnostics.Debug.WriteLine($"镜像文字信息创建成功:");
                System.Diagnostics.Debug.WriteLine($"  原始ID: {originalTextInfo.Id}");
                System.Diagnostics.Debug.WriteLine($"  镜像ID: {mirroredId}");
                System.Diagnostics.Debug.WriteLine($"  文字: {mirroredTextInfo.Text}");
                System.Diagnostics.Debug.WriteLine($"  原始位置: X={originalTextInfo.Position.X:F2}, Y={originalTextInfo.Position.Y:F2}");
                System.Diagnostics.Debug.WriteLine($"  镜像位置: X={mirroredTextInfo.Position.X:F2}, Y={mirroredTextInfo.Position.Y:F2}");
                System.Diagnostics.Debug.WriteLine($"  原始角度: {originalTextInfo.Rotation:F2}°");
                System.Diagnostics.Debug.WriteLine($"  镜像角度: {mirroredTextInfo.Rotation:F2}°");
                System.Diagnostics.Debug.WriteLine($"  高度: {mirroredTextInfo.Height:F2}");
                System.Diagnostics.Debug.WriteLine($"  颜色: {mirroredTextInfo.Color}");
                System.Diagnostics.Debug.WriteLine($"  图层: {mirroredTextInfo.LayerName}");
                System.Diagnostics.Debug.WriteLine($"=== 镜像文字信息创建完成 ===");

                return mirroredTextInfo;
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine($"创建镜像文字信息失败: {ex.Message}");
                System.Diagnostics.Debug.WriteLine($"堆栈跟踪: {ex.StackTrace}");
                return null;
            }
        }



        /// <summary>
        /// 生成镜像实体ID
        /// </summary>
        /// <param name="originalId">原始实体ID</param>
        /// <returns>镜像实体ID</returns>
        private string GenerateMirroredEntityId(string originalId)
        {
            if (string.IsNullOrEmpty(originalId))
                return $"Mirrored_{Guid.NewGuid().ToString("N")}";

            // 提取前缀和后缀
            string prefix = "";
            string suffix = "";

            if (originalId.StartsWith("Text_"))
            {
                prefix = "Text_";
                suffix = originalId.Substring(5);
            }
            else if (originalId.StartsWith("MText_"))
            {
                prefix = "MText_";
                suffix = originalId.Substring(6);
            }
            else if (originalId.StartsWith("Line_"))
            {
                prefix = "Line_";
                suffix = originalId.Substring(5);
            }
            else if (originalId.StartsWith("Circle_"))
            {
                prefix = "Circle_";
                suffix = originalId.Substring(7);
            }
            else if (originalId.StartsWith("Arc_"))
            {
                prefix = "Arc_";
                suffix = originalId.Substring(4);
            }
            else
            {
                // 如果没有识别的前缀，使用通用前缀
                prefix = "Mirrored_";
                suffix = originalId;
            }

            // 生成镜像ID：添加镜像标识符，确保唯一性
            string mirroredId = $"{prefix}Mirrored_{suffix}";

            // 如果镜像ID已存在，添加时间戳确保唯一性
            if (_textInfoMap.ContainsKey(mirroredId))
            {
                string timestamp = DateTime.Now.ToString("HHmmss");
                mirroredId = $"{prefix}Mirrored_{suffix}_{timestamp}";
                System.Diagnostics.Debug.WriteLine($"镜像ID已存在，添加时间戳: {mirroredId}");
            }

            System.Diagnostics.Debug.WriteLine($"生成镜像实体ID: {originalId} -> {mirroredId}");
            return mirroredId;
        }

        /// <summary>
        /// 获取镜像实体ID
        /// </summary>
        /// <param name="originalId">原始ID</param>
        /// <returns>镜像实体ID</returns>
        private string GetMirroredEntityId(string originalId)
        {
            try
            {
                if (string.IsNullOrEmpty(originalId))
                {
                    System.Diagnostics.Debug.WriteLine($"GetMirroredEntityId: 原始ID为空");
                    return null;
                }

                System.Diagnostics.Debug.WriteLine($"=== GetMirroredEntityId被调用 ===");
                System.Diagnostics.Debug.WriteLine($"原始ID: {originalId}");
                System.Diagnostics.Debug.WriteLine($"当前控件ID: {this.ControlId}");
                System.Diagnostics.Debug.WriteLine($"Handle映射表数量: {_handleMapping.Count}");

                // 策略1：通过Handle映射表查找（当本地映射为空时）
                if (_handleMapping.ContainsKey(originalId))
                {
                    var mirroredId = _handleMapping[originalId];
                    System.Diagnostics.Debug.WriteLine($"通过Handle映射表找到镜像ID: {originalId} -> {mirroredId}");
                    System.Diagnostics.Debug.WriteLine($"=== GetMirroredEntityId调用完成 ===");
                    return mirroredId;
                }

                // 策略2：通过反向映射表查找
                if (_reverseHandleMapping.ContainsKey(originalId))
                {
                    var originalIdFromReverse = _reverseHandleMapping[originalId];
                    System.Diagnostics.Debug.WriteLine($"通过反向映射表找到原始ID: {originalId} -> {originalIdFromReverse}");
                    System.Diagnostics.Debug.WriteLine($"=== GetMirroredEntityId调用完成 ===");
                    return originalIdFromReverse;
                }

                // 策略3：通过实体内容匹配查找（基于Handle的实体关联）
                foreach (var kvp in _handleMapping)
                {
                    if (kvp.Value == originalId)
                    {
                        System.Diagnostics.Debug.WriteLine($"通过内容匹配找到镜像ID: {kvp.Key} -> {originalId}");
                        System.Diagnostics.Debug.WriteLine($"=== GetMirroredEntityId调用完成 ===");
                        return kvp.Key;
                    }
                }

                // 策略4：通过全局镜像映射管理器查找（总是尝试，作为兜底策略）
                {
                    System.Diagnostics.Debug.WriteLine($"尝试通过全局镜像映射管理器查找");

                    // 获取当前文档名称，用于在全局映射管理器中查找
                    string documentName = _currentDxfDocument?.Name;
                    System.Diagnostics.Debug.WriteLine($"当前文档名称: {documentName ?? "null"}");

                    if (!string.IsNullOrEmpty(documentName))
                    {
                        // 获取全局映射统计信息
                        var mappingStats = MirrorEntityMappingManager.GetMappingStatistics();
                        System.Diagnostics.Debug.WriteLine($"全局映射管理器中的文档数量: {mappingStats.Count}");
                        foreach (var stat in mappingStats)
                        {
                            System.Diagnostics.Debug.WriteLine($"文档 {stat.Key}: {stat.Value} 个映射");
                        }

                        // 关键修复：总是使用原始文档名称来查询MirrorEntityMappingManager
                        string originalDocumentName = GetOriginalDocumentName(documentName);
                        System.Diagnostics.Debug.WriteLine($"使用原始文档名称查询: {originalDocumentName}");

                        // 调试：查看原始文档名称的映射内容
                        var originalMappings = MirrorEntityMappingManager.GetDocumentMappings(originalDocumentName);
                        System.Diagnostics.Debug.WriteLine($"原始文档 {originalDocumentName} 的映射数量: {originalMappings.Count}");


                        // 策略4.1：通过原始文档名称查找
                        var mirroredHandle = MirrorEntityMappingManager.GetMirroredHandle(originalDocumentName, originalId);
                        if (!string.IsNullOrEmpty(mirroredHandle))
                        {
                            System.Diagnostics.Debug.WriteLine($"通过原始文档名称找到镜像ID: {originalId} -> {mirroredHandle}");
                            System.Diagnostics.Debug.WriteLine($"=== GetMirroredEntityId调用完成 ===");
                            return mirroredHandle;
                        }

                        // 尝试反向查找（如果当前ID是镜像Handle）
                        var originalHandle = MirrorEntityMappingManager.GetOriginalHandle(originalDocumentName, originalId);
                        if (!string.IsNullOrEmpty(originalHandle))
                        {
                            System.Diagnostics.Debug.WriteLine($"通过原始文档名称反向找到原始ID: {originalId} -> {originalHandle}");
                            System.Diagnostics.Debug.WriteLine($"=== GetMirroredEntityId调用完成 ===");
                            return originalHandle;
                        }

                        System.Diagnostics.Debug.WriteLine($"通过原始文档名称未找到映射关系");
                    }
                    else
                    {
                        System.Diagnostics.Debug.WriteLine($"当前文档名称为空，无法在全局映射管理器中查找");
                    }

                    System.Diagnostics.Debug.WriteLine($"未找到镜像ID，返回原始ID: {originalId}");
                    System.Diagnostics.Debug.WriteLine($"=== GetMirroredEntityId调用完成 ===");
                    return originalId; // 如果找不到映射关系，返回原ID
                }
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine($"GetMirroredEntityId异常: {ex.Message}");
                return originalId; // 异常情况下返回原ID
            }
        }

        /// <summary>
        /// 获取原始文档名称（移除"_Mirrored"后缀）
        /// </summary>
        /// <param name="documentName">当前文档名称</param>
        /// <returns>原始文档名称</returns>
        private string GetOriginalDocumentName(string documentName)
        {
            if (string.IsNullOrEmpty(documentName))
                return documentName;

            // 如果文档名称包含"_Mirrored"后缀，移除它
            if (documentName.Contains("_Mirrored"))
            {
                var originalName = documentName.Replace("_Mirrored", "");
                System.Diagnostics.Debug.WriteLine($"文档名称转换: {documentName} -> {originalName}");
                return originalName;
            }

            return documentName;
        }

        /// <summary>
        /// 获取原始实体ID
        /// </summary>
        private string GetOriginalEntityId(string mirroredId)
        {
            if (string.IsNullOrEmpty(mirroredId)) return null;

            System.Diagnostics.Debug.WriteLine($"=== GetOriginalEntityId被调用 ===");
            System.Diagnostics.Debug.WriteLine($"镜像ID: {mirroredId}");
            System.Diagnostics.Debug.WriteLine($"当前控件ID: {this.ControlId}");
            System.Diagnostics.Debug.WriteLine($"反向Handle映射表数量: {_reverseHandleMapping.Count}");

            // 通过反向映射表查找
            if (_reverseHandleMapping.ContainsKey(mirroredId))
            {
                var originalId = _reverseHandleMapping[mirroredId];
                System.Diagnostics.Debug.WriteLine($"通过反向映射表找到原始ID: {mirroredId} -> {originalId}");
                System.Diagnostics.Debug.WriteLine($"=== GetOriginalEntityId调用完成 ===");
                return originalId;
            }

            // 总是尝试通过全局镜像映射管理器查找（作为兜底策略）
            {
                System.Diagnostics.Debug.WriteLine($"GetOriginalEntityId: 尝试通过全局镜像映射管理器查找");

                // 获取当前文档名称
                string documentName = _currentDxfDocument?.Name;
                if (!string.IsNullOrEmpty(documentName))
                {
                    // 关键修复：总是使用原始文档名称来查询MirrorEntityMappingManager
                    string originalDocumentName = GetOriginalDocumentName(documentName);
                    System.Diagnostics.Debug.WriteLine($"GetOriginalEntityId: 使用原始文档名称查询: {originalDocumentName}");

                    // 直接使用带前缀的实体ID进行查找
                    var originalHandle = MirrorEntityMappingManager.GetOriginalHandle(originalDocumentName, mirroredId);
                    if (!string.IsNullOrEmpty(originalHandle))
                    {
                        System.Diagnostics.Debug.WriteLine($"GetOriginalEntityId: 通过原始文档名称找到原始ID: {mirroredId} -> {originalHandle}");
                        System.Diagnostics.Debug.WriteLine($"=== GetOriginalEntityId调用完成 ===");
                        return originalHandle;
                    }

                    // 尝试反向查找（如果当前ID是原始句柄）
                    var mirroredHandle = MirrorEntityMappingManager.GetMirroredHandle(originalDocumentName, mirroredId);
                    if (!string.IsNullOrEmpty(mirroredHandle))
                    {
                        System.Diagnostics.Debug.WriteLine($"GetOriginalEntityId: 通过原始文档名称反向找到镜像ID: {mirroredId} -> {mirroredHandle}");
                        System.Diagnostics.Debug.WriteLine($"=== GetOriginalEntityId调用完成 ===");
                        return mirroredHandle;
                    }

                    System.Diagnostics.Debug.WriteLine($"GetOriginalEntityId: 通过原始文档名称未找到映射关系");
                }
                else
                {
                    System.Diagnostics.Debug.WriteLine($"GetOriginalEntityId: 当前文档名称为空，无法在全局映射管理器中查找");
                }

                System.Diagnostics.Debug.WriteLine($"GetOriginalEntityId: 未找到原始ID，返回null");
                System.Diagnostics.Debug.WriteLine($"=== GetOriginalEntityId调用完成 ===");
                return null;
            }
        }



        /// <summary>
        /// 获取改进的镜像位置（考虑文字基准点和尺寸）
        /// </summary>
        /// <param name="originalPosition">原始位置</param>
        /// <param name="rotation">文字旋转角度</param>
        /// <param name="textHeight">文字高度</param>
        /// <returns>改进的镜像位置</returns>
        private Point3D GetImprovedMirroredPosition(Point3D originalPosition, double rotation, double textHeight)
        {
            try
            {
                // 根据当前控件ID确定是否需要镜像
                if (this.ControlId == "normal")
                {
                    // 原始视图：不需要镜像，返回原始位置
                    System.Diagnostics.Debug.WriteLine($"改进镜像位置计算：原始视图，返回原始位置");
                    return originalPosition;
                }

                // 镜像视图：使用改进的镜像计算逻辑
                var mirrorLine = GetMirrorLine();
                if (mirrorLine != null)
                {
                    // 直接镜像文字的中心位置，不进行复杂的基准点计算
                    var mirroredPosition = CalculateMirroredPositionUsingMirrorLine(originalPosition, mirrorLine.Value);

                    //System.Diagnostics.Debug.WriteLine($"改进镜像位置计算 (简化版):");
                    //System.Diagnostics.Debug.WriteLine($"  原始位置: X={originalPosition.X:F2}, Y={originalPosition.Y:F2}, Z={originalPosition.Z:F2}");
                    //System.Diagnostics.Debug.WriteLine($"  镜像位置: X={mirroredPosition.X:F2}, Y={mirroredPosition.Y:F2}, Z={mirroredPosition.Z:F2}");
                    //System.Diagnostics.Debug.WriteLine($"  镜像线: ({mirrorLine.Value.Start.X:F2}, {mirrorLine.Value.Start.Y:F2}) - ({mirrorLine.Value.End.X:F2}, {mirrorLine.Value.End.Y:F2})");

                    return mirroredPosition;
                }
                else
                {
                    // 如果无法获取动态镜像线，使用默认方法
                    System.Diagnostics.Debug.WriteLine($"警告: 无法获取动态镜像线，使用默认镜像计算");
                    return GetDefaultMirroredPosition(originalPosition);
                }
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine($"改进镜像位置计算失败: {ex.Message}");
                // 返回原始位置作为备选
                return originalPosition;
            }
        }

        /// <summary>
        /// 计算文字方向向量
        /// </summary>
        /// <param name="rotationAngle">旋转角度（度）</param>
        /// <param name="overVector">输出：over方向向量</param>
        /// <param name="upVector">输出：up方向向量</param>
        /// <param name="isMirrored">是否为镜像文字</param>
        private void CalculateTextDirectionVectors(double rotationAngle, out Vector3D overVector, out Vector3D upVector, bool isMirrored = false)
        {
            try
            {
                // 将角度转换为弧度
                double angleRad = rotationAngle * Math.PI / 180.0;

                // 计算cos和sin值
                double cosAngle = Math.Cos(angleRad);
                double sinAngle = Math.Sin(angleRad);

                // 计算over向量（文字的主要方向）
                overVector = new Vector3D(cosAngle, sinAngle, 0);

                // 计算up向量（垂直于over向量，指向Z轴正方向）
                upVector = new Vector3D(-sinAngle, cosAngle, 0);

                // 如果是镜像文字，需要镜像方向向量
                if (isMirrored)
                {
                    // 对于上下镜像关系，Y轴反射，X轴保持不变
                    // 镜像over向量
                    overVector = new Vector3D(overVector.X, -overVector.Y, overVector.Z);

                    // 镜像up向量
                    upVector = new Vector3D(upVector.X, -upVector.Y, upVector.Z);

                    //System.Diagnostics.Debug.WriteLine($"镜像文字方向向量计算:");
                    //System.Diagnostics.Debug.WriteLine($"  原始角度: {rotationAngle:F2}° ({angleRad:F4} rad)");
                    //System.Diagnostics.Debug.WriteLine($"  镜像Over向量: ({overVector.X:F4}, {overVector.Y:F4}, {overVector.Z:F4})");
                    //System.Diagnostics.Debug.WriteLine($"  镜像Up向量: ({upVector.X:F4}, {upVector.Y:F4}, {upVector.Z:F4})");
                }
                else
                {
                    //System.Diagnostics.Debug.WriteLine($"普通文字方向向量计算:");
                    //System.Diagnostics.Debug.WriteLine($"  旋转角度: {rotationAngle:F2}° ({angleRad:F4} rad)");
                    //System.Diagnostics.Debug.WriteLine($"  Over向量: ({overVector.X:F4}, {overVector.Y:F4}, {overVector.Z:F4})");
                    //System.Diagnostics.Debug.WriteLine($"  Up向量: ({upVector.X:F4}, {upVector.Y:F4}, {upVector.Z:F4})");
                }

                // 确保向量是单位向量
                overVector.Normalize();
                upVector.Normalize();
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine($"计算文字方向向量失败: {ex.Message}，使用默认向量");
                // 使用默认向量
                overVector = new Vector3D(1, 0, 0);
                upVector = new Vector3D(0, 0, 1);
            }
        }

        /// <summary>
        /// 计算镜像线的Y坐标
        /// </summary>
        /// <returns>镜像线的Y坐标</returns>
        private double CalculateMirrorLineY()
        {
            try
            {
                // 使用DxfMirrorConverter中的动态镜像线计算，而不是固定的Y=0
                // 获取当前视图的边界框和镜像方向
                var mirrorLine = GetMirrorLine();
                if (mirrorLine != null)
                {
                    // 对于上下镜像关系，使用垂直镜像线（水平直线）
                    // 镜像线的Y坐标是边界框中心点的Y坐标
                    double mirrorLineY = (mirrorLine.Value.Start.Y + mirrorLine.Value.End.Y) / 2;

                    System.Diagnostics.Debug.WriteLine($"镜像线Y坐标计算:");
                    System.Diagnostics.Debug.WriteLine($"  控件ID: {this.ControlId}");
                    System.Diagnostics.Debug.WriteLine($"  动态镜像线Y坐标: {mirrorLineY:F2}");
                    System.Diagnostics.Debug.WriteLine($"  镜像关系: 上下镜像 (Y轴反射)");
                    System.Diagnostics.Debug.WriteLine($"  使用动态镜像线计算");

                    return mirrorLineY;
                }
                else
                {
                    // 如果无法获取动态镜像线，使用默认值
                    System.Diagnostics.Debug.WriteLine($"警告: 无法获取动态镜像线，使用默认Y=0");
                    return 0.0;
                }
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine($"计算镜像线Y坐标失败: {ex.Message}");
                // 返回默认值
                return 0.0;
            }
        }

        /// <summary>
        /// 获取动态镜像线
        /// </summary>
        /// <returns>镜像线的起点和终点</returns>
        private (Vector2 Start, Vector2 End)? GetMirrorLine()
        {
            try
            {
                // 直接使用成员变量定义的边界框，不使用GetCurrentViewBoundingBox
                var boundingBox = new BoundingBox(new Vector2(_minX, _minY), new Vector2(_maxX, _maxY));


                // 根据控件ID确定镜像方向
                // 当控件ID为"mirror"时，表示这是镜像视图，应该进行垂直镜像（上下镜像）
                // 垂直镜像意味着镜像线是水平的，所以使用MirrorDirection.Vertical
                MirrorDirection direction = this.ControlId == "mirror" ? MirrorDirection.Vertical : MirrorDirection.Horizontal;


                // 使用DxfMirrorConverter的逻辑计算镜像线
                var mirrorLine = CalculateMirrorLineFromBoundingBox(boundingBox, direction);

                //System.Diagnostics.Debug.WriteLine($"动态镜像线计算:");
                //System.Diagnostics.Debug.WriteLine($"  边界框: Min({boundingBox.MinPoint.X:F2}, {boundingBox.MinPoint.Y:F2}) - Max({boundingBox.MaxPoint.X:F2}, {boundingBox.MaxPoint.Y:F2})");
                //System.Diagnostics.Debug.WriteLine($"  镜像方向: {direction}");
                //System.Diagnostics.Debug.WriteLine($"  镜像线: ({mirrorLine.Start.X:F2}, {mirrorLine.Start.Y:F2}) - ({mirrorLine.End.X:F2}, {mirrorLine.End.Y:F2})");

                return mirrorLine;
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine($"获取动态镜像线失败: {ex.Message}");
                return null;
            }
        }


        /// <summary>
        /// 根据边界框和镜像方向计算镜像线
        /// </summary>
        /// <param name="boundingBox">边界框</param>
        /// <param name="direction">镜像方向</param>
        /// <returns>镜像线的起点和终点</returns>
        private (Vector2 Start, Vector2 End) CalculateMirrorLineFromBoundingBox(BoundingBox boundingBox, MirrorDirection direction)
        {
            if (direction == MirrorDirection.Horizontal)
            {
                // 水平镜像线（垂直直线）
                // 对于水平镜像，镜像线是垂直的，X坐标在中心
                double x = (boundingBox.MinPoint.X + boundingBox.MaxPoint.X) / 2;
                return (
                    new Vector2(x, boundingBox.MinPoint.Y),
                    new Vector2(x, boundingBox.MaxPoint.Y)
                );
            }
            else
            {
                // 垂直镜像线（水平直线）
                // 对于垂直镜像，镜像线是水平的，Y坐标在中心
                double y = (boundingBox.MinPoint.Y + boundingBox.MaxPoint.Y) / 2;

                //// 添加调试信息
                //System.Diagnostics.Debug.WriteLine($"垂直镜像线计算:");
                //System.Diagnostics.Debug.WriteLine($"  边界框: Min({boundingBox.MinPoint.X:F2}, {boundingBox.MinPoint.Y:F2}) - Max({boundingBox.MaxPoint.X:F2}, {boundingBox.MaxPoint.Y:F2})");
                //System.Diagnostics.Debug.WriteLine($"  镜像线Y坐标: {y:F2}");
                //System.Diagnostics.Debug.WriteLine($"  镜像线: ({boundingBox.MinPoint.X:F2}, {y:F2}) - ({boundingBox.MaxPoint.X:F2}, {y:F2})");

                return (
                    new Vector2(boundingBox.MinPoint.X, y),
                    new Vector2(boundingBox.MaxPoint.X, y)
                );
            }
        }


        /// <summary>
        /// 获取镜像旋转角度
        /// </summary>
        /// <param name="originalRotation">原始旋转角度</param>
        /// <returns>镜像旋转角度</returns>
        private double GetMirroredRotation(double originalRotation)
        {
            try
            {
                // 根据当前控件ID确定是否需要镜像
                if (this.ControlId == "normal")
                {
                    // 原始视图：不需要镜像，返回原始角度
                    System.Diagnostics.Debug.WriteLine($"原始视图：返回原始角度");
                    return originalRotation;
                }

                // 镜像视图：计算镜像角度
                // 对于水平镜像，角度需要取负值
                double mirroredRotation = -originalRotation;

                // 确保角度在0-360度范围内
                while (mirroredRotation < 0)
                {
                    mirroredRotation += 360;
                }
                while (mirroredRotation >= 360)
                {
                    mirroredRotation -= 360;
                }

                System.Diagnostics.Debug.WriteLine($"镜像旋转角度计算:");
                System.Diagnostics.Debug.WriteLine($"  原始角度: {originalRotation:F2}°");
                System.Diagnostics.Debug.WriteLine($"  镜像角度: {mirroredRotation:F2}°");
                System.Diagnostics.Debug.WriteLine($"  角度差: {Math.Abs(mirroredRotation - originalRotation):F2}°");

                // 验证镜像旋转的正确性
                double expectedOriginalRotation = -mirroredRotation;
                while (expectedOriginalRotation < 0)
                {
                    expectedOriginalRotation += 360;
                }
                while (expectedOriginalRotation >= 360)
                {
                    expectedOriginalRotation -= 360;
                }

                double rotationError = Math.Abs(expectedOriginalRotation - originalRotation);
                if (rotationError > 0.1) // 允许0.1度的误差
                {
                    System.Diagnostics.Debug.WriteLine($"警告: 镜像旋转角度计算可能存在误差: {rotationError:F2}°");
                }

                // 镜像旋转验证逻辑：确保镜像角度与原始角度有足够的差异
                double minRotationDifference = 5.0; // 最小角度差异阈值（度）
                double actualRotationDifference = Math.Abs(mirroredRotation - originalRotation);

                // 处理角度跨越360度边界的情况
                if (actualRotationDifference > 180)
                {
                    actualRotationDifference = 360 - actualRotationDifference;
                }

                if (actualRotationDifference < minRotationDifference)
                {
                    System.Diagnostics.Debug.WriteLine($"警告: 镜像旋转角度差异过小，可能影响视觉效果");
                    // 强制增加角度差异
                    if (mirroredRotation > originalRotation)
                    {
                        mirroredRotation = originalRotation + minRotationDifference;
                    }
                    else
                    {
                        mirroredRotation = originalRotation - minRotationDifference;
                    }

                    // 确保角度在0-360度范围内
                    while (mirroredRotation < 0)
                    {
                        mirroredRotation += 360;
                    }
                    while (mirroredRotation >= 360)
                    {
                        mirroredRotation -= 360;
                    }

                    System.Diagnostics.Debug.WriteLine($"调整后的镜像角度: {mirroredRotation:F2}°");
                }

                return mirroredRotation;
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine($"计算镜像旋转角度失败: {ex.Message}");
                // 返回原始角度作为备选
                return originalRotation;
            }
        }

        /// <summary>
        /// 发布镜像同步事件
        /// </summary>
        /// <param name="operation">操作类型</param>
        /// <param name="textInfo">文字信息</param>
        /// <param name="entityId">实体ID（用于删除操作）</param>
        private void PublishMirrorSyncEvent(MirrorSyncOperation operation, TextInfo textInfo = null, string entityId = null)
        {
            try
            {
                // 确定目标控件ID
                string targetControlId = this.ControlId == "normal" ? "mirror" : "normal";

                System.Diagnostics.Debug.WriteLine($"=== 发布镜像同步事件 ===");
                System.Diagnostics.Debug.WriteLine($"当前控件ID: {this.ControlId}");
                System.Diagnostics.Debug.WriteLine($"目标控件ID: {targetControlId}");
                System.Diagnostics.Debug.WriteLine($"操作类型: {operation}");
                System.Diagnostics.Debug.WriteLine($"实体ID: {entityId}");
                System.Diagnostics.Debug.WriteLine($"文字信息: {textInfo?.Text ?? "null"}");

                // 添加详细的TextInfo调试信息
                if (textInfo != null)
                {
                    System.Diagnostics.Debug.WriteLine($"TextInfo详细信息:");
                    System.Diagnostics.Debug.WriteLine($"  Id: '{textInfo.Id ?? "null"}'");
                    System.Diagnostics.Debug.WriteLine($"  Text: '{textInfo.Text ?? "null"}'");
                    System.Diagnostics.Debug.WriteLine($"  Position: {textInfo.Position}");
                    System.Diagnostics.Debug.WriteLine($"  Height: {textInfo.Height}");
                    System.Diagnostics.Debug.WriteLine($"  Rotation: {textInfo.Rotation}");
                    System.Diagnostics.Debug.WriteLine($"  LayerName: '{textInfo.LayerName ?? "null"}'");
                    System.Diagnostics.Debug.WriteLine($"  OriginalEntity: {textInfo.OriginalEntity?.GetType().Name ?? "null"}");

                    // 显示转换后的同步信息
                    var syncInfo = textInfo.ToSyncInfo();
                    System.Diagnostics.Debug.WriteLine($"转换后的同步信息:");
                    System.Diagnostics.Debug.WriteLine($"  Id: '{syncInfo.Id ?? "null"}'");
                    System.Diagnostics.Debug.WriteLine($"  Text: '{syncInfo.Text ?? "null"}'");
                    System.Diagnostics.Debug.WriteLine($"  Position: ({syncInfo.PositionX}, {syncInfo.PositionY}, {syncInfo.PositionZ})");
                }

                // 添加事件聚合器检查
                System.Diagnostics.Debug.WriteLine($"事件发布前检查:");
                System.Diagnostics.Debug.WriteLine($"  当前控件ID: {this.ControlId}");
                System.Diagnostics.Debug.WriteLine($"  目标控件ID: {targetControlId}");
                System.Diagnostics.Debug.WriteLine($"  事件聚合器: {_eventAggregatorInstance != null}");
                if (_eventAggregatorInstance == null)
                {
                    System.Diagnostics.Debug.WriteLine($"错误: 事件聚合器为空！");
                    return;
                }

                // 验证事件参数
                if (!ValidateMirrorSyncEvent(operation, textInfo, entityId))
                {
                    System.Diagnostics.Debug.WriteLine($"镜像同步事件验证失败，跳过发布");
                    return;
                }

                var args = new MirrorSyncEventArgs
                {
                    SourceControlId = this.ControlId,
                    TargetControlId = targetControlId,
                    Operation = operation,
                    TextInfo = textInfo?.ToSyncInfo(),
                    EntityId = entityId
                };

                // 发布镜像同步事件
                _eventAggregatorInstance.GetEvent<MirrorSyncEvent>().Publish(args);

                System.Diagnostics.Debug.WriteLine($"镜像同步事件发布成功: {operation} from {this.ControlId} to {targetControlId}, EntityId: {entityId}");
                System.Diagnostics.Debug.WriteLine($"=== 镜像同步事件发布完成 ===");
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine($"发布镜像同步事件失败: {ex.Message}");
                System.Diagnostics.Debug.WriteLine($"异常堆栈: {ex.StackTrace}");
            }
        }

        /// <summary>
        /// 验证镜像同步事件参数
        /// </summary>
        /// <param name="operation">操作类型</param>
        /// <param name="textInfo">文字信息</param>
        /// <param name="entityId">实体ID</param>
        /// <returns>验证是否通过</returns>
        private bool ValidateMirrorSyncEvent(MirrorSyncOperation operation, TextInfo textInfo, string entityId)
        {
            try
            {
                System.Diagnostics.Debug.WriteLine($"=== 验证镜像同步事件参数 ===");
                System.Diagnostics.Debug.WriteLine($"操作类型: {operation}");

                // 根据操作类型验证参数
                switch (operation)
                {
                    case MirrorSyncOperation.Add:
                        if (textInfo == null)
                        {
                            System.Diagnostics.Debug.WriteLine($"添加操作验证失败: textInfo为空");
                            return false;
                        }
                        if (string.IsNullOrEmpty(textInfo.Id))
                        {
                            System.Diagnostics.Debug.WriteLine($"添加操作验证失败: textInfo.Id为空");
                            return false;
                        }
                        break;

                    case MirrorSyncOperation.Edit:
                        if (textInfo == null)
                        {
                            System.Diagnostics.Debug.WriteLine($"编辑操作验证失败: textInfo为空");
                            return false;
                        }
                        if (string.IsNullOrEmpty(textInfo.Id))
                        {
                            System.Diagnostics.Debug.WriteLine($"编辑操作验证失败: textInfo.Id为空");
                            return false;
                        }
                        break;

                    case MirrorSyncOperation.Delete:
                        if (string.IsNullOrEmpty(entityId))
                        {
                            System.Diagnostics.Debug.WriteLine($"删除操作验证失败: entityId为空");
                            return false;
                        }
                        break;

                    case MirrorSyncOperation.Move:
                        if (textInfo == null)
                        {
                            System.Diagnostics.Debug.WriteLine($"移动操作验证失败: textInfo为空");
                            return false;
                        }
                        if (string.IsNullOrEmpty(textInfo.Id))
                        {
                            System.Diagnostics.Debug.WriteLine($"移动操作验证失败: textInfo.Id为空");
                            return false;
                        }
                        break;

                    case MirrorSyncOperation.Rotate:
                        if (textInfo == null)
                        {
                            System.Diagnostics.Debug.WriteLine($"旋转操作验证失败: textInfo为空");
                            return false;
                        }
                        if (string.IsNullOrEmpty(textInfo.Id))
                        {
                            System.Diagnostics.Debug.WriteLine($"旋转操作验证失败: textInfo.Id为空");
                            return false;
                        }
                        break;

                    case MirrorSyncOperation.Resize:
                        if (textInfo == null)
                        {
                            System.Diagnostics.Debug.WriteLine($"调整大小操作验证失败: textInfo为空");
                            return false;
                        }
                        if (string.IsNullOrEmpty(textInfo.Id))
                        {
                            System.Diagnostics.Debug.WriteLine($"调整大小操作验证失败: textInfo.Id为空");
                            return false;
                        }
                        break;

                    default:
                        System.Diagnostics.Debug.WriteLine($"未知操作类型: {operation}");
                        return false;
                }

                System.Diagnostics.Debug.WriteLine($"镜像同步事件参数验证通过");
                System.Diagnostics.Debug.WriteLine($"=== 验证完成 ===");
                return true;
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine($"验证镜像同步事件参数异常: {ex.Message}");
                return false;
            }
        }


        #endregion

        /// <summary>
        /// Handle映射表：原始Handle -> 镜像Handle（用于镜像实体关联）
        /// </summary>
        private Dictionary<string, string> _handleMapping = new Dictionary<string, string>();

        /// <summary>
        /// 反向Handle映射表：镜像Handle -> 原始Handle
        /// </summary>
        private Dictionary<string, string> _reverseHandleMapping = new Dictionary<string, string>();

        /// <summary>
        /// 实体映射表：原始Handle -> 镜像实体
        /// </summary>
        private Dictionary<string, EntityObject> _entityMapping = new Dictionary<string, EntityObject>();

        /// <summary>
        /// 使用镜像线计算镜像位置
        /// </summary>
        /// <param name="originalPosition">原始位置</param>
        /// <param name="mirrorLine">镜像线</param>
        /// <returns>镜像位置</returns>
        private Point3D CalculateMirroredPositionUsingMirrorLine(Point3D originalPosition, (Vector2 Start, Vector2 End) mirrorLine)
        {
            try
            {
                // 将3D点转换为2D点
                var point2D = new Vector2(originalPosition.X, originalPosition.Y);

                // 使用DxfMirrorConverter的镜像点算法
                var mirroredPoint2D = MirrorPoint2D(point2D, mirrorLine);

                // 转换回3D点，保持Z坐标不变
                var mirroredPosition = new Point3D(mirroredPoint2D.X, mirroredPoint2D.Y, originalPosition.Z);

                // 移除强制位置差异验证逻辑，直接使用计算出的镜像位置
                //System.Diagnostics.Debug.WriteLine($"镜像位置计算完成:");
                //System.Diagnostics.Debug.WriteLine($"  原始位置: ({originalPosition.X:F2}, {originalPosition.Y:F2})");
                //System.Diagnostics.Debug.WriteLine($"  镜像位置: ({mirroredPosition.X:F2}, {mirroredPosition.Y:F2})");

                return mirroredPosition;
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine($"使用镜像线计算镜像位置失败: {ex.Message}");
                return GetDefaultMirroredPosition(originalPosition);
            }
        }

        /// <summary>
        /// 默认镜像位置计算（备用方法）
        /// </summary>
        /// <param name="originalPosition">原始位置</param>
        /// <returns>镜像位置</returns>
        private Point3D GetDefaultMirroredPosition(Point3D originalPosition)
        {
            double mirrorLineY = CalculateMirrorLineY();
            double mirroredY = 2 * mirrorLineY - originalPosition.Y;
            return new Point3D(originalPosition.X, mirroredY, originalPosition.Z);
        }

        /// <summary>
        /// 2D点镜像计算（基于DxfMirrorConverter的算法）
        /// </summary>
        /// <param name="point">原始点</param>
        /// <param name="mirrorLine">镜像线</param>
        /// <returns>镜像点</returns>
        private Vector2 MirrorPoint2D(Vector2 point, (Vector2 Start, Vector2 End) mirrorLine)
        {
            // 检查镜像线是否为水平线（垂直镜像）
            if (Math.Abs(mirrorLine.Start.Y - mirrorLine.End.Y) < 0.001)
            {
                // 水平镜像线（垂直镜像）：Y轴反射，X轴保持不变
                double mirrorY = mirrorLine.Start.Y;
                double mirroredY = 2 * mirrorY - point.Y;

                //System.Diagnostics.Debug.WriteLine($"水平镜像线镜像计算:");
                //System.Diagnostics.Debug.WriteLine($"  原始点: ({point.X:F2}, {point.Y:F2})");
                //System.Diagnostics.Debug.WriteLine($"  镜像线Y坐标: {mirrorY:F2}");
                //System.Diagnostics.Debug.WriteLine($"  镜像点: ({point.X:F2}, {mirroredY:F2})");

                return new Vector2(point.X, mirroredY);
            }
            else if (Math.Abs(mirrorLine.Start.X - mirrorLine.End.X) < 0.001)
            {
                // 垂直镜像线（水平镜像）：X轴反射，Y轴保持不变
                double mirrorX = mirrorLine.Start.X;
                double mirroredX = 2 * mirrorX - point.X;

                //System.Diagnostics.Debug.WriteLine($"垂直镜像线镜像计算:");
                //System.Diagnostics.Debug.WriteLine($"  原始点: ({point.X:F2}, {point.Y:F2})");
                //System.Diagnostics.Debug.WriteLine($"  镜像线X坐标: {mirrorX:F2}");
                //System.Diagnostics.Debug.WriteLine($"  镜像点: ({mirroredX:F2}, {point.Y:F2})");

                return new Vector2(mirroredX, point.Y);
            }
            else
            {
                // 通用镜像线：使用投影方法
                System.Diagnostics.Debug.WriteLine($"通用镜像线镜像计算:");

                // 计算点到镜像线的向量
                var lineVector = mirrorLine.End - mirrorLine.Start;
                var pointVector = point - mirrorLine.Start;

                // 计算投影
                var projection = Vector2.DotProduct(pointVector, lineVector) / (lineVector.X * lineVector.X + lineVector.Y * lineVector.Y);
                var projectedPoint = mirrorLine.Start + lineVector * projection;

                // 计算镜像点
                var mirroredPoint = point + 2 * (projectedPoint - point);

                //System.Diagnostics.Debug.WriteLine($"  原始点: ({point.X:F2}, {point.Y:F2})");
                //System.Diagnostics.Debug.WriteLine($"  镜像线: ({mirrorLine.Start.X:F2}, {mirrorLine.Start.Y:F2}) - ({mirrorLine.End.X:F2}, {mirrorLine.End.Y:F2})");
                //System.Diagnostics.Debug.WriteLine($"  镜像点: ({mirroredPoint.X:F2}, {mirroredPoint.Y:F2})");

                return mirroredPoint;
            }
        }


        /// <summary>
        /// 获取改进的镜像旋转角度（考虑文字对齐方式和镜像方向）
        /// </summary>
        /// <param name="originalRotation">原始旋转角度</param>
        /// <returns>改进的镜像旋转角度</returns>
        private double GetImprovedMirroredRotation(double originalRotation)
        {
            try
            {
                // 根据当前控件ID确定是否需要镜像
                if (this.ControlId == "normal")
                {
                    // 原始视图：不需要镜像，返回原始角度
                    System.Diagnostics.Debug.WriteLine($"改进镜像旋转角度计算：原始视图，返回原始角度");
                    return originalRotation;
                }

                // 镜像视图：使用改进的镜像角度计算逻辑
                var mirrorLine = GetMirrorLine();
                if (mirrorLine != null)
                {
                    // 根据镜像线方向确定镜像角度计算方式
                    double mirroredRotation;

                    if (mirrorLine.Value.Start.X == mirrorLine.Value.End.X)
                    {
                        // 垂直镜像线（水平镜像）
                        // 对于水平镜像，需要考虑文字的对齐方式
                        mirroredRotation = CalculateHorizontalMirrorRotation(originalRotation);
                    }
                    else
                    {
                        // 水平镜像线（垂直镜像）
                        // 对于垂直镜像，角度变化更复杂
                        mirroredRotation = CalculateVerticalMirrorRotation(originalRotation);
                    }

                    // 确保角度在0-360度范围内
                    while (mirroredRotation < 0)
                    {
                        mirroredRotation += 360;
                    }
                    while (mirroredRotation >= 360)
                    {
                        mirroredRotation -= 360;
                    }

                    //System.Diagnostics.Debug.WriteLine($"改进镜像旋转角度计算:");
                    //System.Diagnostics.Debug.WriteLine($"  原始角度: {originalRotation:F2}°");
                    //System.Diagnostics.Debug.WriteLine($"  镜像角度: {mirroredRotation:F2}°");
                    //System.Diagnostics.Debug.WriteLine($"  角度差: {Math.Abs(mirroredRotation - originalRotation):F2}°");
                    //System.Diagnostics.Debug.WriteLine($"  镜像线方向: {(mirrorLine.Value.Start.X == mirrorLine.Value.End.X ? "垂直" : "水平")}");

                    return mirroredRotation;
                }
                else
                {
                    // 如果无法获取动态镜像线，使用默认方法
                    System.Diagnostics.Debug.WriteLine($"警告: 无法获取动态镜像线，使用默认镜像角度计算");
                    return GetMirroredRotation(originalRotation);
                }
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine($"改进镜像旋转角度计算失败: {ex.Message}");
                // 返回原始角度作为备选
                return originalRotation;
            }
        }


        /// <summary>
        /// 计算水平镜像的旋转角度
        /// </summary>
        /// <param name="originalRotation">原始旋转角度</param>
        /// <returns>水平镜像后的旋转角度</returns>
        private double CalculateHorizontalMirrorRotation(double originalRotation)
        {
            try
            {
                // 水平镜像：Y轴反射，X轴保持不变
                // 对于文字，需要考虑其基准点和方向
                double mirroredRotation = 360 - originalRotation;

                // 确保角度在0-360度范围内
                while (mirroredRotation < 0)
                {
                    mirroredRotation += 360;
                }
                while (mirroredRotation >= 360)
                {
                    mirroredRotation -= 360;
                }

                System.Diagnostics.Debug.WriteLine($"水平镜像旋转角度计算:");
                System.Diagnostics.Debug.WriteLine($"  原始角度: {originalRotation:F2}°");
                System.Diagnostics.Debug.WriteLine($"  镜像角度: {mirroredRotation:F2}°");

                return mirroredRotation;
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine($"计算水平镜像旋转角度失败: {ex.Message}");
                return originalRotation;
            }
        }

        /// <summary>
        /// 计算垂直镜像的旋转角度
        /// </summary>
        /// <param name="originalRotation">原始旋转角度</param>
        /// <returns>垂直镜像后的旋转角度</returns>
        private double CalculateVerticalMirrorRotation(double originalRotation)
        {
            try
            {
                // 首先确保输入角度在0~360度范围内
                while (originalRotation < 0)
                {
                    originalRotation += 360;
                }
                while (originalRotation >= 360)
                {
                    originalRotation -= 360;
                }

                double mirroredRotation;

                // 1) 0与180，270与90的特殊映射
                if (originalRotation == 0)
                {
                    mirroredRotation = 180;
                }
                else if (originalRotation == 180)
                {
                    mirroredRotation = 0;
                }
                else if (originalRotation == 90)
                {
                    mirroredRotation = 270;
                }
                else if (originalRotation == 270)
                {
                    mirroredRotation = 90;
                }
                // 2) 0~180之间的角度（不包括180）：直接返回-角度
                else if (originalRotation > 0 && originalRotation < 180)
                {
                    mirroredRotation = -originalRotation;
                }
                // 3) 180~270之间的角度（不包括270）：角度-90
                else if (originalRotation > 180 && originalRotation < 270)
                {
                    mirroredRotation = 360 - originalRotation;
                }
                // 4) 270~360之间的角度（不包括360）：360-角度
                else if (originalRotation > 270 && originalRotation < 360)
                {
                    mirroredRotation = 360 - originalRotation;
                }
                else
                {
                    // 对于边界值，使用默认处理
                    mirroredRotation = 180 - originalRotation;
                }

                // 确保结果在0-360度范围内
                while (mirroredRotation < 0)
                {
                    mirroredRotation += 360;
                }
                while (mirroredRotation >= 360)
                {
                    mirroredRotation -= 360;
                }

                //System.Diagnostics.Debug.WriteLine($"垂直镜像旋转角度计算:");
                //System.Diagnostics.Debug.WriteLine($"  原始角度: {originalRotation:F2}°");
                //System.Diagnostics.Debug.WriteLine($"  镜像角度: {mirroredRotation:F2}°");               
                return mirroredRotation;
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine($"计算垂直镜像旋转角度失败: {ex.Message}");
                return originalRotation;
            }
        }
    }

}

// 单元测试：验证镜像角度计算的正确性
#if DEBUG
public static class MirrorRotationTests
{
    /// <summary>
    /// 测试垂直镜像角度计算
    /// 输入: [0, 90, 180, 270] => 输出: [180, 270, 0, 90]
    /// 额外测试: [45, 135, 225, 315] => 输出: [135, 45, 315, 225]
    /// 非主要角度测试: [20, 30] => 输出: [340, 330]
    /// </summary>
    public static void TestVerticalMirrorRotation()
    {
        Console.WriteLine("=== 垂直镜像角度计算单元测试 ===");

        // 测试数据：输入角度和期望输出角度（基于新的分段条件逻辑）
        var testCases = new[]
        {
            // 主要测试用例：90度增量
            new { Input = 0.0, Expected = 180.0 },      // 0° → 180° (特殊映射)
            new { Input = 90.0, Expected = 270.0 },     // 90° → 270° (特殊映射)
            new { Input = 180.0, Expected = 0.0 },      // 180° → 0° (特殊映射)
            new { Input = 270.0, Expected = 90.0 },     // 270° → 90° (特殊映射)
            
            // 额外测试用例：45度增量
            new { Input = 45.0, Expected = 315.0 },     // 45° → -45° → 315° (0~180范围)
            new { Input = 135.0, Expected = 225.0 },    // 135° → -135° → 225° (0~180范围)
            new { Input = 225.0, Expected = 135.0 },    // 225° → 225° - 90° = 135° (180~270范围)
            new { Input = 315.0, Expected = 45.0 },     // 315° → 360° - 315° = 45° (270~360范围)
            
            // 非主要角度测试用例
            new { Input = 20.0, Expected = 340.0 },     // 20° → -20° → 340° (0~180范围)
            new { Input = 30.0, Expected = 330.0 }      // 30° → -30° → 330° (0~180范围)
        };

        bool allTestsPassed = true;

        foreach (var testCase in testCases)
        {
            // 模拟新的分段条件逻辑
            double originalRotation = testCase.Input;
            double mirroredRotation;

            // 首先确保输入角度在0~360度范围内
            while (originalRotation < 0)
            {
                originalRotation += 360;
            }
            while (originalRotation >= 360)
            {
                originalRotation -= 360;
            }

            // 1) 0与180，270与90的特殊映射
            if (originalRotation == 0)
            {
                mirroredRotation = 180;
            }
            else if (originalRotation == 180)
            {
                mirroredRotation = 0;
            }
            else if (originalRotation == 90)
            {
                mirroredRotation = 270;
            }
            else if (originalRotation == 270)
            {
                mirroredRotation = 90;
            }
            // 2) 0~180之间的角度（不包括180）：直接返回-角度
            else if (originalRotation > 0 && originalRotation < 180)
            {
                mirroredRotation = -originalRotation;
            }
            // 3) 180~270之间的角度（不包括270）：角度-90
            else if (originalRotation > 180 && originalRotation < 270)
            {
                mirroredRotation = originalRotation - 90;
            }
            // 4) 270~360之间的角度（不包括360）：360-角度
            else if (originalRotation > 270 && originalRotation < 360)
            {
                mirroredRotation = 360 - originalRotation;
            }
            else
            {
                // 对于边界值，使用默认处理
                mirroredRotation = 180 - originalRotation;
            }

            // 确保结果在0-360度范围内
            while (mirroredRotation < 0)
            {
                mirroredRotation += 360;
            }
            while (mirroredRotation >= 360)
            {
                mirroredRotation -= 360;
            }

            bool testPassed = Math.Abs(mirroredRotation - testCase.Expected) < 0.001;

            Console.WriteLine($"测试: {testCase.Input:F1}° → {mirroredRotation:F1}° (期望: {testCase.Expected:F1}°) - {(testPassed ? "通过" : "失败")}");

            if (!testPassed)
            {
                allTestsPassed = false;
            }
        }

        Console.WriteLine($"=== 测试结果: {(allTestsPassed ? "全部通过" : "有失败")} ===");

        // 如果测试失败，抛出异常
        if (!allTestsPassed)
        {
            throw new Exception("垂直镜像角度计算单元测试失败！");
        }
    }

    /// <summary>
    /// 运行所有镜像角度计算测试
    /// </summary>
    public static void RunAllTests()
    {
        try
        {
            TestVerticalMirrorRotation();
            Console.WriteLine("所有测试通过！");
        }
        catch (Exception ex)
        {
            Console.WriteLine($"测试失败: {ex.Message}");
        }
    }
}
#endif


